Pal*_*han 5 c++ multithreading pthreads shared-memory
我为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;
};
Run Code Online (Sandbox Code Playgroud)
我能够看到这个锁在一个进程中的常规线程之间正常工作,但是当我运行进程A时,它在共享内存区域中执行以下操作:
void* mem; //some shared memory from shm_open
MyLock* myLock = new(mem) MyLock;
//loop sleeping random amounts and calling ->lock and ->unlock
Run Code Online (Sandbox Code Playgroud)
然后进程B打开共享内存对象(通过设置它与内存的相同区域的字符组合进行验证)并执行以下操作:
MyLock* myLock = reinterpret_cast<MyLock*>(mem);
//same loop for locking and unlocking as process A
Run Code Online (Sandbox Code Playgroud)
但是当尝试使用backpce锁定导致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
Run Code Online (Sandbox Code Playgroud)
该调用是在重新解释将内存转换为内存之后的第一次锁定调用MyLock*.如果我在崩溃过程中将myLock的内容转储到gdb中,我看到:
{
attr = {
__size = "\003\000\000\200",
__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 = "\001\000\000\000\000 //etc,
__align = 1
}
}
Run Code Online (Sandbox Code Playgroud)
所以它看起来没问题(在其他进程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]