【问题标题】:boost::condition_variable and lockboost::condition_variable 和锁
【发布时间】:2012-02-02 19:39:39
【问题描述】:
boost::condition_variable cond;
boost::mutex mut;

//thread1
{
"read_socket()"
cond.notify_one();
}

//thread2
{
for(;;)
{
...
boost::unique_lock<boost::mutex> lock(mut);
cond.wait(lock);
}
}

boost::condition_variable cond;
boost::mutex mut;

//thread1
{
"read_socket()"
boost::unique_lock<boost::mutex> lock(mut);
cond.notify_one();
}

//thread2
{
for(;;)
{
...
boost::unique_lock<boost::mutex> lock(mut);
cond.wait(lock);
}

如果我在调用 cond.notify_one() 之前省略了锁会有影响吗?

【问题讨论】:

  • cond.wait(lock) 可以在调用notify_one() 之前恢复。您应该始终 wait 在循环中,每次都测试 条件(或使用带有谓词的重载)。

标签: c++ multithreading boost


【解决方案1】:

C++11 标准对notify_onenotify_all 没有任何要求;因此,当您发出 condition_variable 信号时,不要持有锁就可以了。但是,信号线程通常需要持有锁,直到它设置等待线程唤醒后检查的条件。如果没有,该程序可能包含比赛。例如,请参阅这个 SO 问题:Boost synchronization

【讨论】:

  • 然而,等待调用使用的锁似乎没有用,因为它只被等待使用
【解决方案2】:

thread2 唤醒时,它将尝试重新获取锁。如果thread1 持有锁,thread2 将阻塞直到thread1 释放锁。

在此处显示的代码中,这不会显着影响行为。如果您要在cond.notify_one(); 之后在thread1 中添加任何行为,则该行为将保证在thread2 仅在第二个代码块中继续之前执行。

或者,您可以在进入 for 循环之前在 thread2 中构造唯一锁,而不是在等待条件变量之前。这将确保thread1 在尝试构造自己的唯一锁时阻塞,直到thread2 等待信号,前提是thread1thread2 初始化并进入循环之前没有执行。这将允许您保证 thread1 不会发送任何 thread2 未等待的通知。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多