使用共享内存时遇到一些麻烦

Posted

技术标签:

【中文标题】使用共享内存时遇到一些麻烦【英文标题】:get some trouble with using shared memory 【发布时间】:2013-05-25 13:16:09 【问题描述】:

我正在尝试使用共享内存中的指针编译代码。我想使用 mutex 变量来检查是否可以进行进程间同步。但是 Xcode 给了我错误“解析问题”预期表达式“并以红色突出显示行*(pthread_mutex_t*)shm_addr = PTHREAD_MUTEX_INITIALIZER;。 这是代码。

#include <sys/ipc.h>
#include <sys/shm.h>
#include <pthread.h>
#include <stdio.h>
#include <stdlib.h>

#define KEY_NUM 9527
#define MEM_SIZE 4096

pthread_mutex_t test;
int main(int argc, char * argv[])

    int     shm_id;
    void    *shm_addr;

    if( (shm_id = shmget((key_t)KEY_NUM, MEM_SIZE, IPC_CREAT | 0666)) == -1)
    
        printf("fail to allocate a shared memory.\n");
        return -1;
    

    if((shm_addr = shmat(shm_id, (void*)0,0)) == (void*)-1)
    
        printf("fail to attach shared memory.\n");
        return -1;
    

    *(pthread_mutex_t*)shm_addr     = PTHREAD_MUTEX_INITIALIZER; // error.


    test                            = PTHREAD_MUTEX_INITIALIZER; 
    // this statement works well.
    *(int*)(shm_addr+64) = 10000; // this statement also works well.

    // information useful to you.
    // sizeof(pthread_mutex_t*) : 64
    // OS X Mountain Lion 64bits
    return 0;

我不知道为什么。有人可以帮忙吗?

谢谢。

【问题讨论】:

一旦你得到这个编译,我希望你在做的事情上会有其他问题。请参阅 Jens Gustedt @JensGustedt 下面的 cmets。 我已经删除了我之前的答案,但你为什么要将 shm_addr 转换为 pthread_mutex?您应该创建一个单独的 pthread_mutex 并对其进行初始化,它与共享内存地址不同。 pthread_mutex_t myMutex; pthread_mutex_init(&amp;myMutex, 0); pthread_mutex_lock(&amp;myMutex); etc... 您锁定了互斥体,而不是内存指针本身,并在互斥体被锁定时执行您的工作。如果每个线程在访问内存之前都使用了互斥锁,那么它就是互斥访问。 (它不像 Java 那样在对象本身上进行同步。) 另见***.com/questions/2584678/… 您看到我对您删除的答案的评论了吗?这是我的评论:六个进程将使用共享内存。一个进程只读取共享内存,另外 5 个进程只写入。将值写入共享内存并读取共享内存中的值可能存在竞争条件问题。所以,我决定使用共享内存的一部分作为互斥变量。在共享内存中写入和读取值之前,我已经预料到了声明 pthread_mutex_lock((pthread_mutex_t*)shm_addr)。声明pthread_mutex_unlock((pthread_mutex_t*)shm_addr) 在共享内存中写入和读取值后。; 【参考方案1】:

要在共享内存中使用互斥锁,您首先需要一个支持此功能的系统(您没有告诉我们),然后您必须相应地初始化互斥锁。宏 PTHREAD_MUTEX_INITIALIZER 不适用于此,您必须使用正确的参数集动态使用 pthread_mutex_init

与此相关的文本始终是 POSIX 标准,您可以通过搜索 name_of_the_function_you_are_interested_in 和“opengroup”轻松找到。这里pthread_mutex_init 声明:

在默认互斥属性合适的情况下,宏 PTHREAD_MUTEX_INITIALIZER 可用于初始化互斥锁 静态分配。效果相当于动态 通过使用参数 attr 调用 pthread_mutex_init() 进行初始化 指定为 NULL,但不执行错误检查。

而函数pthread_mutexattr_setpshared 的相关部分指出:

进程共享属性设置为 PTHREAD_PROCESS_SHARED 以 允许任何有权访问的线程操作互斥锁 分配互斥锁的内存,即使互斥锁是 分配在多个进程共享的内存中。如果 进程共享属性为 PTHREAD_PROCESS_PRIVATE,互斥体应 只能由在同一进程中创建的线程操作 初始化互斥锁的线程;如果线程不同 进程试图对这样的互斥体进行操作,行为是 不明确的。 属性的默认值为PTHREAD_PROCESS_PRIVATE

另外,在现代系统和新代码中,不要使用古老的shmat 调用。现代的替代品是shm_openmmap 的组合。

【讨论】:

您能否更详细地解释一下为什么上面代码中的tempMutex 不能在共享内存中使用?或者任何页面都会很棒。另外,我已经评论了我在上面的答案上写的程序。

以上是关于使用共享内存时遇到一些麻烦的主要内容,如果未能解决你的问题,请参考以下文章

两个进程之间的命名共享内存

python进程线程:共享内存

用户可能无法在 Linux 系统上打开共享内存对象的原因

Windows 驱动程序 - 来自用户模式的共享内存 -> 内核模式

如何使用命名共享内存?

Python进程间通信之共享内存