首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >boost::interprocess::interprocess_condition::wait在等待时不会自动解锁互斥锁

boost::interprocess::interprocess_condition::wait在等待时不会自动解锁互斥锁
EN

Stack Overflow用户
提问于 2013-06-13 23:03:29
回答 2查看 562关注 0票数 0

正如当前的帖子标题所说,boost boost::interprocess::interprocess_condition::wait应该在等待时自动解锁互斥锁,但它没有。

在以下代码中:

代码语言:javascript
复制
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

有没有人有建议?

谢谢。

EN

回答 2

Stack Overflow用户

发布于 2013-06-14 17:51:05

根据到目前为止的评论,我想我可以推断出一个答案。

不要信任您传递给interprocess_condition::wait()的scoped_lock的成员。interprocess_condition的契约(与interprocess_condition_any不同)规定,您只能将其与interprocess_mutex的锁一起使用。了解了这一点,条件变量将内部互斥锁从锁中拉出,以便比它对锁一无所知的情况下更有效地完成其工作。

因此,当涉及到解锁互斥锁时,它不会在scoped_lock上调用unlock(),而是直接在互斥锁上调用。这对于内部实现来说是很好的;不要在家里这样做。如果在锁超出作用域之前不重新锁定互斥,就会发生不好的事情。

换句话说,您在调试器中看到的行为并不表示存在问题。如果你有一个死锁,那一定是在别的地方。

编辑

在我看来,实际代码中的条件变量没有问题。我发现与start_mut的交互有点奇怪。您确定这部分没有问题吗?

票数 0
EN

Stack Overflow用户

发布于 2013-06-14 23:23:20

好的,这是第一个线程:

代码语言:javascript
复制
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.");
        }
    }
   }
}

第二个线程尝试使用以下方法发送数据:

代码语言:javascript
复制
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时阻塞,因为第一个线程正在等待它。

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/17090496

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档