正如当前的帖子标题所说,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中,我按下了pause,当我看到state_access_lock在等待时仍然被锁定时,我感到很惊讶。
但boost的医生并不是这么说的,here。
有没有人有建议?
谢谢。
发布于 2013-06-14 17:51:05
根据到目前为止的评论,我想我可以推断出一个答案。
不要信任您传递给interprocess_condition::wait()的scoped_lock的成员。interprocess_condition的契约(与interprocess_condition_any不同)规定,您只能将其与interprocess_mutex的锁一起使用。了解了这一点,条件变量将内部互斥锁从锁中拉出,以便比它对锁一无所知的情况下更有效地完成其工作。
因此,当涉及到解锁互斥锁时,它不会在scoped_lock上调用unlock(),而是直接在互斥锁上调用。这对于内部实现来说是很好的;不要在家里这样做。如果在锁超出作用域之前不重新锁定互斥,就会发生不好的事情。
换句话说,您在调试器中看到的行为并不表示存在问题。如果你有一个死锁,那一定是在别的地方。
编辑
在我看来,实际代码中的条件变量没有问题。我发现与start_mut的交互有点奇怪。您确定这部分没有问题吗?
发布于 2013-06-14 23:23:20
好的,这是第一个线程:
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时阻塞,因为第一个线程正在等待它。
https://stackoverflow.com/questions/17090496
复制相似问题