c++ wait_for方法互斥锁中谓词的内容是否受保护?

Is the content of a predicate in c++ wait_for method mutex protected or not?

提问人:Sami 提问时间:11/21/2022 最后编辑:DailyLearnerSami 更新时间:11/21/2022 访问量:315

问:

假设 countMe 是一个全局变量,并且我同时向这个 while 循环启动 10 个线程,变量 countMe 互斥锁在谓词中是否受到保护? 我认为因为当代码到达wait_for时,它会解锁并释放锁,所以变量 countMe 不受互斥锁保护。我说得对吗?

while (true)
{
    std::unique_lock<std::mutex> lock(mtx_kill);
    cv_kill.wait_for(lock, 500ms, [&]() {++countMe; return killFlag; });

    if (killFlag)
    {
        break;
    }
}
C++ 多线程 互斥谓

评论


答:

4赞 Sam Varshavchik 11/21/2022 #1

我说得对吗?

不,你错了。

我认为是因为当代码到达wait_for时,它会解锁 lock,变量 countMe 不受多文本保护。

否,当 lambda 被评估时,互斥锁处于锁定状态。保证。

cppreference.com 用 来描述wait_for的谓词版本描述如下wait_until

while (!stop_waiting()) {
    if (wait_until(lock, timeout_time) == std::cv_status::timeout) {
        return stop_waiting();
    }
}

请注意,互斥锁的初始状态是它已锁定。谓词,这里称为“stop_waiting”,总是在互斥锁处于锁定状态时调用。

你可以把它看作是一个无谓词,而附加的谓词检查是一个离散的、单独的步骤。返回后,互斥锁会重新锁定,这发生在谓词 lambda 执行之前。如果它投了反对票,互斥锁将再次以原子方式解锁,条件变量将再次等待。wait_forwaitwait

P.S. 上面的讨论假设你总是在其他地方被访问,并持有相同的锁。这是你的问题所假定的,但只是正式指出。countMe

评论

0赞 Sami 11/21/2022
谢谢你的解释。在while循环之前是否应该有类似'std::unique_lock<std::mutex> lk(cv_m);'之类的东西,也应该是'cv_m.wait_unitl(lock, timeout_time) == std::cv_status::timeout)'?
1赞 Sam Varshavchik 11/26/2022
好吧,是否应该有,不仅需要完全理解这个执行线程,还需要完全理解所有其他执行线程的逻辑,这里没有显示。显然,这将改变锁定的范围。由此产生的逻辑更改是否是它们应该的样子,这是您需要弄清楚的事情。