为什么pthread_mutex_t尝试锁定来自两个不同进程的共享内存时会出现段错误
Why does pthread_mutex_t segfault when trying to lock through shared memory from two different processes?
我为一个pthread_mutex_t编写了一个超级简单的包装器,用于两个进程之间:
//basic version just to test using it between two processes
struct MyLock
{
public:
MyLock() {
pthread_mutexattr_init(&attr);
pthread_mutexattr_setpshared(&attr, PTHREAD_PROCESS_SHARED);
pthread_mutexattr_settype(&attr, PTHREAD_MUTEX_ADAPTIVE_NP);
pthread_mutex_init(&lock, &attr);
}
~MyLock() {
pthread_mutex_destroy(&lock);
pthread_mutexattr_destroy(&attr);
}
lock() {
pthread_mutex_lock(&lock);
}
unlock() {
pthread_mutex_unlock(&lock);
}
private:
pthread_mutexattr_t attr;
pthread_mutex_t lock;
};
我能够看到此锁在进程中的常规线程之间正常工作,但是当我运行进程 A 时,它在共享内存区域中执行以下操作:
void* mem; //some shared memory from shm_open
MyLock* myLock = new(mem) MyLock;
//loop sleeping random amounts and calling ->lock and ->unlock
然后进程 B 打开共享内存对象(通过使用字符组合将其设置为同一内存区域来验证)并执行以下操作:
MyLock* myLock = reinterpret_cast<MyLock*>(mem);
//same loop for locking and unlocking as process A
但是在尝试使用回溯锁定导致libpthread.so.0中的pthread_mutex_lock()时处理B段错误
我做错了什么?
我从进程 B 获得的回溯如下所示:
in pthread_mutex_lock () from /lib64/libpthread.so.0
in MyLock::lock at MyLock.H:50
in Server::setUpSharedMemory at Server.C:59
in Server::Server at Server.C
in main.C:52
该调用是重新解释将内存转换为MyLock*
后的第一个锁定调用。如果我在崩溃过程中将 MyLock 的内容转储到 gdb 中,我会看到:
{
attr = {
__size = " 03 00 00200",
__align = -2147483645
},
lock = {
__data = {
__lock = 1
__count = 0,
__owner = 6742, //this is the lightweight process id of a thread in process A
__nusers = 1,
__kind = 131,
__spins = 0,
__list = {
__prev = 0x0,
__Next = 0x0
}
},
__size = " 01 00 00 00 00 //etc,
__align = 1
}
}
所以它看起来不错(在其他进程 GDB 中看起来也是这样)。我正在使用其他优化标志将两个应用程序编译在一起。
您没有发布代码来打开和初始化共享内存区域,但我怀疑该部分可能是造成您的问题的原因。
由于pthread_mutex_t
比"字符组合"大得多,因此应通过读取和写入更长的 (~ KB) 字符串来检查shm_open(3)
- ftruncate(2)
- mmap(2)
序列。
不要忘记检查两个端点是否真的可以写入 shm 区域,并且写入的数据对另一端是否真正可见。
进程 A:[打开并初始化 shm]-[编写 AAA...AA]-[睡眠5秒]-[阅读BBB...BB]-[关闭thm]
进程B:(一两秒后)[打开shm]-[阅读AAA...AA]-[写BBB...BB]-[关闭thm]
我有一个类似的问题,其中编写器进程是根用户,而读取器进程是普通用户(硬件守护程序的情况)。一旦调用任何pthread_mutex_lock()
或pthread_cond_wait()
及其解锁对应项,这将在读取器中出现段错误。
我通过使用适当的 umask 修改 SHM 文件权限来解决它:
作家
umask(!S_IRUSR|!S_IWUSR|!S_IRGRP|!S_IWGRP|!S_IROTH|!S_IWOTH);
FD=shm_open("the_SHM_file", O_CREAT|O_TRUNC|O_RDWR, S_IRUSR|S_IWUSR|S_IRGRP|S_IWGRP|S_IROTH|S_IWOTH);
ftruncate(FD, 28672);
SHM=mmap(0, 28672, PROT_READ|PROT_WRITE, MAP_SHARED, FD, 0);
读者
FD=shm_open("the_SHM_file", O_RDWR, S_IRUSR|S_IWUSR|S_IRGRP|S_IWGRP|S_IROTH|S_IWOTH);
SHM=mmap(0, 28672, PROT_READ|PROT_WRITE, MAP_SHARED, A.FD, 0);
你没有说你正在使用什么操作系统,但你没有检查pthread_mutexattr_setpshared
调用的返回值。 您的操作系统可能不支持共享互斥锁,并且此调用失败。
- 是否可以通过C++扩展强制多个python进程共享同一内存
- 使用Boost Interprocess创建托管共享内存需要很长时间
- 多个"常量引用"变量可以共享同一个内存吗?
- 使用共享指针时,从共享指针本身释放内存的机制是什么
- 字符串共享内存映射的向量
- CUDA 使用共享内存平铺 3D 卷积实现
- 共享内存:MapViewOfFile 返回错误 5
- 在共享缓冲区内存中创建 ::std::string 对象
- 如何在多写入器情况下对文件支持的共享内存中的大页面出错
- Directx 12 :在两个进程之间共享图形内存
- 有没有办法列出所有共享内存对象的名称?
- 子进程更新共享 mmap 内存,但父进程没有更改
- C++线程之间的内存共享
- 使用Windows共享内存共享小数据
- 更有效地使用fork()和写时复制内存共享
- 从托管代码到非托管代码跨共享内存共享整数数组
- 通过内存共享c++对象
- 内存共享;继承;基实例和派生实例;c++
- Matlab与c++在MEX中的内存共享
- 跨共享内存共享 std::字符串