当通过boost::interprocesss::managed_shared_memory
对象使用基于pthread的健壮互斥锁从一个进程向另一个进程发出信号时,我注意到存在以下问题:a)取决于启动顺序和/或b)行为改变时进程重新启动。问题的症结在于,在某些条件下,我的示例应用程序中的信号(通过条件变量)没有被接收。
我已经在git-https://github.com/zerodefect/mutex_example中发布了(最小)代码示例。我试图使代码示例尽可能简短,但是它仍然跨越几个文件。我希望在这种情况下可以链接到GitHub中的存储库吗?
我有2个进程-process_b:
while (true)
{
// Notify 'Process A' every 2 seconds.
std::this_thread::sleep_for(std::chrono::seconds(2));
pthread_cond_signal(pCv);
std::cout << "Info: Signaled" << std::endl;
}
仅尝试向process_a发出信号:
while (true)
{
if (!timed_lock_mutex(pMutex, std::chrono::seconds(5)))
{
std::cout << "Warning: Mutex wait timeout." << std::endl;
continue;
}
BOOST_SCOPE_EXIT(pMutex)
{
unlock_mutex(pMutex);
} BOOST_SCOPE_EXIT_END
if (!wait_for_cv(pCv, pMutex, std::chrono::seconds(10)))
{
std::cout << "Warning: Wait timeout!" << std::endl;
continue;
}
std::cout << "Info: Received notification." << std::endl;
}
问题方案
方案1:
方案2:
问题:
环境:
答案 0 :(得分:0)
我的猜测是您的代码锁是因为您永远不会破坏共享内存 https://theboostcpplibraries.com/boost.interprocess-shared-memory
如果从不调用remove(),则即使程序终止,共享内存也会继续存在。是否自动删除共享内存取决于基础操作系统。重新启动系统后,Windows和许多Unix操作系统(包括Linux)会自动删除共享内存。
因此,过程尝试在pthread_cond_wait
调用中获取 condvar内部互斥锁的锁,但是在先前的运行中已将其锁定。而且由于您没有退出逻辑,因此您肯定会杀死进程,从而永远不会释放锁。流程B同样如此。
您创建的互斥体是健壮的互斥体这一事实无关紧要。因为不是它,所以您被锁定等待。 ...但是我实际上不确定您还在等什么。不确定condvar内部futex的属性是什么。需要进一步调查。但是从观察到的行为来看,它并不可靠。
顺便说一句,您获得但不使用流程B中的共享互斥。但是也许,也许,您应该Calling pthread_cond_signal without locking mutex
还有另外一件事:pthread_cond_timedwait
可以返回EOWNERDEAD
,您必须检查您的wait_for_cv()