如果线程涉及互斥锁定和解锁之间的循环,则在 C++ 中的 2 个线程之间切换执行
Switching of execution between 2 threads in C++, if threads involve a loop between mutex lock & unlock
我有一个字符串向量,它是一个共享资源。
std::vector<std::string> vecstr;
有 2 个 运行 并行的线程:
线程 1:将字符串插入共享资源。
Thread2: 计算共享资源的大小。
std::mutex mt;
void f1()
{
mt.lock();
while(some_condition())
{
std::string str = getStringFromSomewhere();
vecstr.push_back(str);
}
mt.unlock();
}
size_t f2()
{
mt.lock();
while(string_sending_hasEnded())
{
size_t size = vecstr.size();
}
mt.unlock();
}
int main()
{
std::thread t1(f1);
std::thread t2(f2);
t1.join();
t2.join();
}
我的问题是:如果 t1 线程在整个 while 循环持续时间内保持 vecstr 共享资源互斥锁锁定,t2 将如何获取共享资源 vecstr 来计算它的大小?
执行是否在 2 个线程之间保持切换,或者取决于谁获得第一个互斥锁。因此,如果 T1 获得了互斥锁,那么它只会在 while 循环结束后才释放它?这是真的 ?或者执行在 2 个线程之间不断切换。
If any one of the thread is going to hijack the execution by not
allowing other thread to be switched in between then how do i handle
such a scenario with while/for loops in each thread but both threads
needs to be continuously executed ? Where I want both the threads to
keep switching their execution. Shall I lock and unlock inside the
while loop, so that each iteration has mutex locked & unlocked ?
So if T1 got hold of mutex then it will release it only after while loop ends ? Is this true ?
是的,没错。
在执行这些循环的整个过程中,任何一个线程都会锁定 mt
互斥锁。
至于
If that's the case how do i handle such a scenario ? Where I want both the threads to keep switching their execution. Shall I lock and unlock inside the while loop, so that each iteration has mutex locked & unlocked
是的,使用更细粒度的锁定,仅针对 change/access 向量的操作:
std::mutex mt;
void f1() {
while(some_condition()) {
std::string str = getStringFromSomewhere();
{ std::unique_lock(mt); // -+
vecstr.push_back(str); // | locked
} // -+
}
}
size_t f2() {
while(string_sending_hasEnded()) {
size_t size = 0;
{ std::unique_lock(mt); // -+
size = vecstr.size(); // | locked
} // -+
}
}
我还强烈建议使用锁卫(如我示例中的 std::unique_lock
),而不是自己手动使用 lock()
unock()
。所以互斥锁被解锁是安全的,例如以防抛出异常。
你明白了。如果你想在现实生活中成功地使用互斥锁,你将只让互斥锁查找尽可能少的时间。例如,就在 push_back() 和 size() 调用附近。
但实际上,您首先需要做的是弄清楚您的程序应该做什么,然后使用互斥锁来确保实现它。目前我知道你想要 运行 一些线程,但这不是你想要实现的。
我有一个字符串向量,它是一个共享资源。
std::vector<std::string> vecstr;
有 2 个 运行 并行的线程:
线程 1:将字符串插入共享资源。
Thread2: 计算共享资源的大小。
std::mutex mt;
void f1()
{
mt.lock();
while(some_condition())
{
std::string str = getStringFromSomewhere();
vecstr.push_back(str);
}
mt.unlock();
}
size_t f2()
{
mt.lock();
while(string_sending_hasEnded())
{
size_t size = vecstr.size();
}
mt.unlock();
}
int main()
{
std::thread t1(f1);
std::thread t2(f2);
t1.join();
t2.join();
}
我的问题是:如果 t1 线程在整个 while 循环持续时间内保持 vecstr 共享资源互斥锁锁定,t2 将如何获取共享资源 vecstr 来计算它的大小? 执行是否在 2 个线程之间保持切换,或者取决于谁获得第一个互斥锁。因此,如果 T1 获得了互斥锁,那么它只会在 while 循环结束后才释放它?这是真的 ?或者执行在 2 个线程之间不断切换。
If any one of the thread is going to hijack the execution by not allowing other thread to be switched in between then how do i handle such a scenario with while/for loops in each thread but both threads needs to be continuously executed ? Where I want both the threads to keep switching their execution. Shall I lock and unlock inside the while loop, so that each iteration has mutex locked & unlocked ?
So if T1 got hold of mutex then it will release it only after while loop ends ? Is this true ?
是的,没错。
在执行这些循环的整个过程中,任何一个线程都会锁定 mt
互斥锁。
至于
If that's the case how do i handle such a scenario ? Where I want both the threads to keep switching their execution. Shall I lock and unlock inside the while loop, so that each iteration has mutex locked & unlocked
是的,使用更细粒度的锁定,仅针对 change/access 向量的操作:
std::mutex mt;
void f1() {
while(some_condition()) {
std::string str = getStringFromSomewhere();
{ std::unique_lock(mt); // -+
vecstr.push_back(str); // | locked
} // -+
}
}
size_t f2() {
while(string_sending_hasEnded()) {
size_t size = 0;
{ std::unique_lock(mt); // -+
size = vecstr.size(); // | locked
} // -+
}
}
我还强烈建议使用锁卫(如我示例中的 std::unique_lock
),而不是自己手动使用 lock()
unock()
。所以互斥锁被解锁是安全的,例如以防抛出异常。
你明白了。如果你想在现实生活中成功地使用互斥锁,你将只让互斥锁查找尽可能少的时间。例如,就在 push_back() 和 size() 调用附近。
但实际上,您首先需要做的是弄清楚您的程序应该做什么,然后使用互斥锁来确保实现它。目前我知道你想要 运行 一些线程,但这不是你想要实现的。