如果线程涉及互斥锁和放大器之间的循环,则在C ++中在2个线程之间切换执行。开锁

时间:2017-07-16 13:39:04

标签: c++ multithreading c++11 thread-safety mutex

我是一个共享资源的字符串向量。

std::vector<std::string> vecstr;

有两个并行运行的线程:

Thread1:将字符串插入共享资源。

线程2:计算共享资源的大小。

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线程保持vecstr共享资源互斥锁被锁定整个while循环持续时间t2如何获取共享资源vecstr来计算它的大小? 执行是否继续在2个线程之间切换,或者取决于谁拥有互斥锁1。因此,如果T1获得了互斥锁,那么只有在while循环结束后它才会释放它?这是真的 ?或者执行继续在2个线程之间切换。

  

如果任何一个线程都没有劫持执行   允许其他线程之间切换然后如何处理   这种情况在每个线程中都有while / for循环但两个线程   需要继续执行?我想要两个线程的地方   继续切换他们的执行。我要锁定并解锁   while循环,以便每次迭代都有互斥锁定&amp;解锁?

2 个答案:

答案 0 :(得分:3)

你明白了。如果您想在现实生活中成功使用互斥锁,您将保留互斥锁,只查看可能的最短时间。例如,围绕push_back()和size()调用。

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

答案 1 :(得分:2)

  

因此,如果T1获得了互斥锁,那么只有在while循环结束后它才会释放它?这是真的吗?

是的,那是真的。

任何一个线程都会在执行这些循环的整个时间内锁定mt互斥锁。

至于your comment

  

如果是这样,我该如何处理这种情况?我想让两个线程继续切换它们的执行。我应该在while循环内锁定和解锁,这样每次迭代都会锁定互斥锁。解锁

是使用更细粒度的锁定,仅用于更改/访问向量的操作:

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()。因此,互斥锁将被解锁是安全的,例如如果抛出异常。