gpt4 book ai didi

c++ - 持有 boost::interprocess::scoped_lock 时 sleep 导致它永远不会被释放

转载 作者:太空狗 更新时间:2023-10-29 11:30:51 25 4
gpt4 key购买 nike

我根据 the reference 使用 boost::interprocess::shared_memory_objectLinux 上执行 IPC (匿名互斥示例)。

有一个服务器进程,它创建 shared_memory_object 并写入它,同时持有一个包裹在 scoped_lock 中的 interprocess_mutex;以及一个客户端进程,它打印其他进程所写的任何内容 - 在本例中,它是一个 int

我遇到了一个问题:如果服务器在持有互斥锁时处于休眠状态,则客户端进程永远无法获取它并永远等待。

错误的服务器循环:

using namespace boost::interprocess;
int n = 0;
while (1) {
std::cerr << "acquiring mutex... ";
{
// "data" is a struct on the shared mem. and contains a mutex and an int
scoped_lock<interprocess_mutex> lock(data->mutex);
data->a = n++;
std::cerr << n << std::endl;
sleep(1);
} // if this bracket is placed before "sleep", everything works
}

服务器输出:

acquiring mutex... 1
acquiring mutex... 2
acquiring mutex... 3
acquiring mutex... 4

客户端循环:

while(1) {
std::cerr << "acquiring mutex... ";
{
scoped_lock<interprocess_mutex> lock(data->mutex);
std::cerr << data->a << std::endl;
}
sleep(1);
}

客户端输出(永远等待):

acquiring mutex...

问题是,如果我将括号移动到 sleep 调用之前的行,一切正常。为什么?我不认为使用锁定的互斥锁 sleep 会导致互斥锁永远锁定。

我的唯一理论是,当内核唤醒服务器进程时,作用域结束并且互斥锁被释放,但等待进程没有机会运行。服务器然后重新获取锁...但这似乎没有多大意义。

谢谢!

最佳答案

你的理论是正确的。

如果您查看所链接引用中匿名互斥锁示例的底部,您会看到

As we can see, a mutex is useful to protect data but not to notify to another process an event.

释放互斥量不会通知任何其他可能正在等待它的人,并且由于您的进程刚刚醒来,它几乎肯定有足够的调度时间片来做更多的工作。它将循环并在再次休眠之前重新获取互斥锁,这是客户端必须自己获取互斥锁的第一个机会。

将服务器 sleep() 移到范围之外意味着它会在互斥量空闲时进入休眠状态,让客户端有机会运行并为自己获取互斥量。

如果您想放弃处理器,但仍然在您的范围内休眠,请尝试调用 sched_yield()(仅限 Linux)。 sleep(0) 也可能有效。

关于c++ - 持有 boost::interprocess::scoped_lock 时 sleep 导致它永远不会被释放,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/977265/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com