如果线程涉及互斥锁定和解锁之间的循环,则在 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 将如何获取共享资源 vec​​str 来计算它的大小? 执行是否在 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() 调用附近。

但实际上,您首先需要做的是弄清楚您的程序应该做什么,然后使用互斥锁来确保实现它。目前我知道你想要 运行 一些线程,但这不是你想要实现的。