Boost::interprocess::interprocess_condition::wait在等待时不会自动解锁互
boost::interprocess::interprocess_condition::wait does not atomically unlock mutex while waiting
正如当前的帖子标题所说,boost boost::interprocess::interprocess_condition::wait应该在等待时自动解锁互斥锁,但它没有。
在以下代码中:
boost::interprocess::scoped_lock< boost::interprocess::interprocess_mutex > state_access_lock(impl->state->state_access_mut);
impl->state->state_access_cond.wait(state_access_lock);
在VS2010进入调试模式时,我按下暂停,当我看到state_access_lock在等待时仍然被锁定时,我感到很惊讶。
但这不是boost的doc在这里说的。
有人有什么建议吗?
谢谢。
这是第一个线程:
void CSharedMemory::start(start_mode mode)
{
bool start_mut_locked = true;
impl->running = true;
impl->mode = mode;
stateMetaStruct* state = impl->proc_state;
boost::interprocess::scoped_lock< boost::interprocess::interprocess_mutex > state_access_lock(state->state_access_mut);
while(impl->running)
{
state->data_written = false;
while(!state->data_written)
{
if(start_mut_locked)
{
// We can now unlock and let other threads to send data.
impl->start_mut.unlock();
start_mut_locked = false;
}
state->state_access_cond.wait(state_access_lock); // wait here upon sharedmemory's state change
boost::interprocess::offset_ptr< stateMetaStruct > s = impl->shm_obj.find< stateMetaStruct >(boost::interprocess::unique_instance).first;
state = s.get();
if(!state->data_written)
{
// Spurious wakeup.
glm_debug("Spurious wakeup.");
}
if(this == state->data_written_by_proccess)
{
state->data_written = false;
glm_debug("Ignoring my proper event.");
}
}
if(impl->running)
{
// Got action from other process.
const interprocess_actions state_action = state->action;
if(DO_STOP == state_action) {
}
else if(DUMP_USERS_REQUEST == state_action) {
impl->stateChangedListener->onDumpUsersRequest();
}
else if(DUMP_USERS_REPLY == state_action) {
}
else {
glm_err("Unexpected state.");
}
}
}
}
第二个线程尝试使用这个方法发送数据:
void CSharedMemory::sendDumpUsersRequest()
{
// Ensure shm is started.
boost::mutex::scoped_lock lk(impl->start_mut);
glm_debug("%s", __FUNCTION__);
boost::interprocess::offset_ptr< stateMetaStruct > s = impl->shm_obj.find< stateMetaStruct >(boost::interprocess::unique_instance).first;
stateMetaStruct* state = s.get();
boost::interprocess::scoped_lock< boost::interprocess::interprocess_mutex > state_access_lock(state->state_access_mut);
state->action = DUMP_USERS_REQUEST;
state->data_written = true;
state->data_written_by_proccess = this;
// Send request.
state->state_access_cond.notify_all();
}
行为是,当尝试获取scoped_mutex时,第二个线程阻塞,因为第一个线程正在等待它。
根据目前的评论,我想我可以推断出一个答案。
不要相信传递给interprocess_condition::wait()的scoped_lock的成员。interprocess_condition的约定(与interprocess_condition_any不同)表明,您只能将其与interprocess_mutex的锁一起使用。知道了这一点,条件变量就会把内部互斥锁从锁中取出来,比它不知道锁的情况下更有效地完成它的工作。
所以当要解锁互斥锁时,它不会在scoped_lock上调用unlock(),而是直接在互斥锁上调用。这对于内部实现来说是没问题的;不要在家里这样做。如果没有在互斥锁超出作用域之前重新锁定互斥锁,就会发生不好的事情。
换句话说,您在调试器中看到的行为并不表明存在问题。如果你有死锁,它一定在别的地方。
编辑
给出的实际代码中的条件变量对我来说看起来很好。我发现与start_mut的交互有点奇怪。你确定那部分没问题吗?
相关文章:
- 我应该在锁定TBitmap画布后解锁它吗
- 虚假唤醒是否会解锁所有等待线程,甚至是不相关的线程?
- c++ 为什么我不应该从不同的线程解锁互斥锁
- 在新作用域中使用unique_lock是否等效于在使用共享资源的工作结束时解锁调用
- "data race"(不是真的)在通知条件变量并解锁关联的互斥锁后
- 程序输入密码并解锁窗口7,8,10
- 在通知之前完成手动解锁
- STD :: Mutex如何在不同的线程中解锁
- 如何使用单个解锁方法(可称为读取器或写入器)实现C++读写器锁?
- 如何在C 中自动汇总日志消息并自动解锁互斥X
- 如果我们已经手动解锁了unique_lock,那么破坏时会解锁吗?
- 正在解锁手动未定义/不良设计的锁定guard
- 从C 运行代码后解锁绑定(在R中)的问题
- 在功能返回之前,可以解锁Mutex会增加并发
- 当互斥锁解锁时,它会notify_all或notify_one
- 如何确保在C ++中解锁储物柜?哪种解决方案更好
- 我应该如何在一个功能中锁定wxMutex,并在另一个功能中将其解锁
- mutex::lock() 检查一次解锁状态是否已经被另一个线程锁定?
- 在Qt 5.4中可以对互斥对象进行两次解锁吗
- Boost::interprocess::interprocess_condition::wait在等待时不会自动解锁互