共享内存中的健壮互斥锁不是那么健壮
Robust mutex in shared memory not so robust
当通过对象使用基于pthread的健壮互斥体从一个进程到另一个进程发出信号时boost::interprocesss::managed_shared_memory
我注意到存在以下问题: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:
- 启动进程 A
- 启动进程 B(未收到信号(
场景 2:
- 启动进程 B
- 启动进程 A(此时工作(
- 重新启动进程 B(停止接收信号(
问题:
- 我是否正确使用了提升的managed_shared_memory对象?
- 我是否正确配置了互斥锁?
环境:
- Linux via Ubuntu 18.04.3 LTS
- 海湾合作委员会 v8.3.0
- 提升 v1.55
更新:@Jorge Bellon 发现了互斥锁/condition_variable被初始化两次的问题。解决后,该程序现在在简历中抓住 当它锁定时,堆栈跟踪显示为:
process_a:
futex_wait 0x00007ffff7bc3602
futex_wait_simple 0x00007ffff7bc3602
__condvar_acquire_lock 0x00007ffff7bc3602
__condvar_cancel_waiting 0x00007ffff7bc3602
__pthread_cond_wait_common 0x00007ffff7bc40bd
__pthread_cond_timedwait 0x00007ffff7bc40bd
wait_until cv_utils.cpp:73
wait_for_cv cv_utils.cpp:93
main main_process_a.cpp:85
__libc_start_main 0x00007ffff6fe6b97
_start 0x000055555555734a
process_b:
futex_wait 0x00007ffff7bc44b0
futex_wait_simple 0x00007ffff7bc44b0
__condvar_quiesce_and_switch_g1 0x00007ffff7bc44b0
__pthread_cond_signal 0x00007ffff7bc44b0
main main_process_b.cpp:73
__libc_start_main 0x00007ffff6fe6b97
_start 0x00005555555573aa
我的猜测是你的代码锁,因为你永远不会破坏共享内存 https://theboostcpplibraries.com/boost.interprocess-shared-memory
如果从未调用 remove((,则即使程序终止,共享内存也将继续存在。是否自动删除共享内存取决于底层操作系统。Windows和许多Unix操作系统,包括Linux,一旦系统重新启动,就会自动删除共享内存。
因此,进程 A 尝试在调用pthread_cond_wait
获取condvar 内部互斥锁,但它已经在以前的运行中被锁定。而且因为你没有退出逻辑,所以你肯定会杀死进程,从而永远不会释放锁。流程 B 也是如此。
您创建的互斥锁是健壮的互斥锁这一事实无关紧要。因为这不是你被锁定等待的。 ...但我实际上不确定你还在等什么。不确定 condvar 内部 futex 的性质是什么。需要进一步调查。但从观察到的行为来看,它并不稳健。
顺便说一下,您可以在进程 B 中获取但不使用共享互斥锁。但也许,只是也许,你应该在不锁定互斥锁的情况下调用pthread_cond_signal 还有一件事:pthread_cond_timedwait
可以返回EOWNERDEAD
,您必须在wait_for_cv()
中检查该错误
- 是否可以通过C++扩展强制多个python进程共享同一内存
- 使用Boost Interprocess创建托管共享内存需要很长时间
- 多个"常量引用"变量可以共享同一个内存吗?
- 使用共享指针时,从共享指针本身释放内存的机制是什么
- 字符串共享内存映射的向量
- CUDA 使用共享内存平铺 3D 卷积实现
- 共享内存:MapViewOfFile 返回错误 5
- 在共享缓冲区内存中创建 ::std::string 对象
- 如何在多写入器情况下对文件支持的共享内存中的大页面出错
- Directx 12 :在两个进程之间共享图形内存
- 有没有办法列出所有共享内存对象的名称?
- 子进程更新共享 mmap 内存,但父进程没有更改
- C++线程之间的内存共享
- 使用Windows共享内存共享小数据
- 更有效地使用fork()和写时复制内存共享
- 从托管代码到非托管代码跨共享内存共享整数数组
- 通过内存共享c++对象
- 内存共享;继承;基实例和派生实例;c++
- Matlab与c++在MEX中的内存共享
- 跨共享内存共享 std::字符串