c++ - 为什么 pthread_mutex_t 在尝试通过来自两个不同进程的共享内存进行锁定时会出现段错误?

标签 c++ multithreading pthreads shared-memory

我为打算在两个进程之间使用的 pthread_mutex_t 编写了一个 super 简单的包装器:

//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 = "\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     
  }
}

所以它看起来不错(在其他进程 gdb 中也是如此)。我正在同时编译这两个应用程序,也不使用额外的优化标志。

最佳答案

您没有发布打开和初始化共享内存区域的代码,但我怀疑这部分可能是您问题的原因。

因为 pthread_mutex_t 比“字符组合”大得多,所以你应该检查你的 shm_open(3)-ftruncate(2)- mmap(2) 读取和写入更长 (~ KB) 字符串的序列。

不要忘记检查两个端点是否真的可以写入 shm 区域,并且写入的数据对另一端是否真的可见。

进程A:[打开并初始化shm]-[写入AAA...AA]-[休眠5秒]-[读取BBB...BB]-[关闭thm]

进程 B:(一两秒后)[打开 shm]-[读取 AAA...AA]-[写入 BBB...BB]-[关闭 thm]

关于c++ - 为什么 pthread_mutex_t 在尝试通过来自两个不同进程的共享内存进行锁定时会出现段错误?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/22800016/

相关文章:

c - 如果线程中发生fork调用,fork进程从哪里开始?

C++ 运算符 []

c# - 如何在数据库更改时更新 WPF UI

c - 我将如何使用 pthreads 使这个 udpclient 异步?

c++ - 通过引用线程函数传递 unique_ptr 的托管对象

c - C语言中输入数值时如何将光标移动到鼠标位置?

c - 避免线程间竞争条件的彼得森算法

c++ - LNK1104 : cannot open file 'libboost_program_options-vc100-mt-sgd-1_56.lib'

C++ 继承练习

C++ 从 istream 读取直到换行(但不是空格)