【问题标题】:How do I synchronize access to shared memory in LynxOS/POSIX?如何在 LynxOS/POSIX 中同步对共享内存的访问?
【发布时间】:2011-02-04 19:04:26
【问题描述】:

我正在一个LynxOS SE(POSIX 兼容)系统上实现两个进程,它们将通过共享内存进行通信。

一个进程将充当“生产者”,而另一个进程将充当“消费者”。在多线程系统中,我的解决方法是使用互斥锁和 condvar(条件变量)对,当共享内存已更新。

如何在多进程而非多线程架构中实现这一点?

是否有 LynxOS/POSIX 方法来创建可在进程之间使用的 condvar/mutex 对?
或者在这种情况下是否有其他同步机制更合适?

【问题讨论】:

  • 谢谢@nos,我注意到有一个pthread_condattr_setpshared,但我错过了pthread_attr_setscope。如果您将评论更改为答案,我会投赞成票。
  • 看来我有点误会了,pthread_condattr_setpshared 确实是你会使用的,pthread_attr_setscope 处理线程调度。

标签: c ipc posix shared-memory lynxos


【解决方案1】:

您可以使用共享内存/信号量 IPC 来实现这一点。

这是一个很好的例子:

http://www-personal.washtenaw.cc.mi.us/~chasselb/linux275/ClassNotes/ipc/shared_mem.htm

【讨论】:

    【解决方案2】:

    这是通过unnamed POSIX semaphores 完成的,即信号量本身被放置在共享内存中。

    【讨论】:

    • 使用未命名的 POSIX 信号量代替 命名 POSIX 信号量有什么好处吗?
    • 通过避免系统调用,在非竞争情况下,未命名信号量在进程之间的速度非常快。
    【解决方案3】:

    创建进程共享互斥量/条件的标准方法。变量是使用您设置 pthread_mutexattr_setpshared/pthread_condattr_setpshared 的属性来初始化它们。检查 LynxOS 是否支持。

    您自然需要放置这样的互斥锁/条件。共享内存中的变量,所以所有进程都可以使用它。

    【讨论】:

    • 谢谢@nos。我稍微扩展了你的答案。
    【解决方案4】:

    感谢@nos,但我想稍微扩展他的回答。
    最后(为了清楚起见,不包括错误处理)我做了如下:

    1。定义共享内存结构

    这包含进程间同步对象和要共享的数据。

    typedef struct
    {
        // Synchronisation objects
        pthread_mutex_t ipc_mutex;
        pthread_cond_t  ipc_condvar;
        // Shared data
        int number;
        char data[1024];
    } shared_data_t;
    

    2。创建共享内存并设置大小(主进程)

    在Master进程上创建一个新的共享内存对象:

    fd = shm_open(SHAREDMEM_FILENAME, O_CREAT|O_EXCL|O_RDWR, S_IRUSR|S_IWUSR);
    ftruncate(fd, sizeof(shared_data_t));
    

    2。或者打开共享内存(从属进程)

    在 Slave 上只需附加到现有对象:

    fd = shm_open(SHAREDMEM_FILENAME, O_RDWR, S_IRUSR|S_IWUSR);
    

    3。映射到进程空间

    // Specify addr of calling address, mostly use NULL is most portable way
    shared_data_t* sdata = (shared_data_t*)mmap(NULL, sizeof(shared_data_t), PROT_READ|PROT_WRITE, MAP_SHARED, fd, 0);
    close(fd);
    

    4。初始化同步变量(仅限主进程)

    pthread_mutexattr_t mutex_attr;
    pthread_mutexattr_init(&mutex_attr);
    pthread_mutexattr_setpshared(&mutex_attr, PTHREAD_PROCESS_SHARED);
    pthread_mutex_init(&sdata->ipc_mutex, &mutex_attr);
    
    pthread_condattr_t cond_attr;
    pthread_condattr_init(&cond_attr);
    pthread_condattr_setpshared(&cond_attr, PTHREAD_PROCESS_SHARED);
    pthread_cond_init(&sdata->ipc_condvar, &cond_attr);
    

    就是这样。

    现在可以正常使用 Mutex 和 cond 来控制对共享数据的访问。

    唯一真正的问题是确保主进程已创建共享内存并在从属进程启动之前初始化同步变量。并确保根据需要整理 munmap()shm_unlink()

    注意:XSI 替代方案

    POSIX:XSI 扩展具有其他共享内存的功能(shmget()shmat() 等)可能更有用如果它们可用,但它们不在 LynxOS 版本上-SE 我正在使用。

    【讨论】:

    • 注意:我们在 LynxOS 上遇到了这种方法的问题。如果在设置之前映射了任何其他内存,那么它将失败。见stackoverflow.com/questions/2782883/…
    • 在从属进程的#2 代码中,我还必须在调用 shm_open 之后调用 ftruncate(fd, sizeof(shared_data_t))。只是 shm_open 的参数在 #2 的主从之间有所不同。如果在从属设备中没有 ftruncate,当尝试在结构末尾使用灵活的数组成员时,我会遇到 EFAULT 和其他错误。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2016-05-25
    • 1970-01-01
    • 2014-10-08
    • 2021-11-26
    • 1970-01-01
    • 2019-10-22
    • 1970-01-01
    相关资源
    最近更新 更多