共享内存中的条件变量 - 此代码符合 POSIX 标准吗?

2023-11-25

POSIX 标准是否允许named包含互斥锁和条件变量的共享内存块?

我们一直在尝试使用互斥锁和条件变量来同步同一计算机上两个进程对命名共享内存的访问。LynuxWorks LynxOS-SE系统(符合 POSIX)。

一个共享内存块被称为"/sync"并包含互斥锁和条件变量,另一个是"/data"并包含我们正在同步访问的实际数据。

我们看到了失败pthread_cond_signal()如果两个进程都不执行mmap()来电完全相同的顺序,或者如果一个进程映射到其他映射之前的一块共享内存"/sync" memory.

这个示例代码是我能做到的最短的代码:

#include <sys/types.h>
#include <sys/stat.h>
#include <sys/mman.h>
#include <sys/file.h>
#include <stdlib.h>
#include <pthread.h>
#include <errno.h>
#include <iostream>
#include <string>
using namespace std;

static const string shm_name_sync("/sync");
static const string shm_name_data("/data");

struct shared_memory_sync
{
  pthread_mutex_t mutex;
  pthread_cond_t condition;
};

struct shared_memory_data
{
  int a;
  int b;
};


//Create 2 shared memory objects
// - sync contains 2 shared synchronisation objects (mutex and condition)
// - data not important 
void create()
{
  // Create and map 'sync' shared memory
  int fd_sync = shm_open(shm_name_sync.c_str(), O_CREAT|O_RDWR, S_IRUSR|S_IWUSR);
  ftruncate(fd_sync, sizeof(shared_memory_sync));
  void* addr_sync = mmap(0, sizeof(shared_memory_sync), PROT_READ|PROT_WRITE, MAP_SHARED, fd_sync, 0);
  shared_memory_sync* p_sync = static_cast<shared_memory_sync*> (addr_sync);

    // init the cond and mutex
  pthread_condattr_t cond_attr;
    pthread_condattr_init(&cond_attr);
    pthread_condattr_setpshared(&cond_attr, PTHREAD_PROCESS_SHARED);
    pthread_cond_init(&(p_sync->condition), &cond_attr);
    pthread_condattr_destroy(&cond_attr);

    pthread_mutexattr_t m_attr;
    pthread_mutexattr_init(&m_attr);
    pthread_mutexattr_setpshared(&m_attr, PTHREAD_PROCESS_SHARED);
    pthread_mutex_init(&(p_sync->mutex), &m_attr);
    pthread_mutexattr_destroy(&m_attr);

  // Create the 'data' shared memory   
  int fd_data = shm_open(shm_name_data.c_str(), O_CREAT|O_RDWR, S_IRUSR|S_IWUSR);
  ftruncate(fd_data, sizeof(shared_memory_data));
  
  void* addr_data = mmap(0, sizeof(shared_memory_data), PROT_READ|PROT_WRITE, MAP_SHARED, fd_data, 0);
  shared_memory_data* p_data = static_cast<shared_memory_data*> (addr_data);

  // Run the second process while it sleeps here.
  sleep(10);

  int res = pthread_cond_signal(&(p_sync->condition));
  assert(res==0);  // <--- !!!THIS ASSERT WILL FAIL ON LYNXOS!!!

  munmap(addr_sync, sizeof(shared_memory_sync));
  shm_unlink(shm_name_sync.c_str());
  munmap(addr_data, sizeof(shared_memory_data));
  shm_unlink(shm_name_data.c_str());
}

//Open the same 2 shared memory objects but in reverse order
// - data
// - sync 
void open()
{
  sleep(2);
  int fd_data = shm_open(shm_name_data.c_str(), O_RDWR, S_IRUSR|S_IWUSR);
  void* addr_data = mmap(0, sizeof(shared_memory_data), PROT_READ|PROT_WRITE, MAP_SHARED, fd_data, 0);
  shared_memory_data* p_data = static_cast<shared_memory_data*> (addr_data);

  int fd_sync = shm_open(shm_name_sync.c_str(), O_RDWR, S_IRUSR|S_IWUSR);
  void* addr_sync = mmap(0, sizeof(shared_memory_sync), PROT_READ|PROT_WRITE, MAP_SHARED, fd_sync, 0);
  shared_memory_sync* p_sync = static_cast<shared_memory_sync*> (addr_sync);

  // Wait on the condvar
  pthread_mutex_lock(&(p_sync->mutex));
  pthread_cond_wait(&(p_sync->condition), &(p_sync->mutex));
  pthread_mutex_unlock(&(p_sync->mutex));
  
  munmap(addr_sync, sizeof(shared_memory_sync));
  munmap(addr_data, sizeof(shared_memory_data));
}

int main(int argc, char** argv) 
{
  if(argc>1)
  {
    open(); 
  }
  else
  {
    create();
  }

    return (0);
}

运行没有参数的程序,然后运行另一个带有参数的副本,第一个程序将在断言检查时失败pthread_cond_signal()。 但改变一下顺序open()功能为mmap() the "/sync” 之前的记忆"/data"一切都会很好。

对我来说,这似乎是 LynxOS 中的一个主要错误,但 LynuxWorks 声称 POSIX 标准未涵盖以这种方式在命名共享内存中使用互斥锁和条件变量,因此他们不感兴趣。

谁能确定这段代码是否确实违反了 POSIX?
或者有人有任何令人信服的文档证明它符合 POSIX 标准吗?

Edit: 我们知道PTHREAD_PROCESS_SHARED是 POSIX 并受 LynxOS 支持。争论的焦点是互斥体和信号量是否可以在命名共享内存中使用(就像我们所做的那样),或者 POSIX 是否只允许在一个进程创建并映射共享内存然后分叉第二个进程时使用它们。


The pthread_mutexattr_setpshared函数可用于允许任何有权访问该内存的线程(甚至不同进程中的线程)访问共享内存中的 pthread 互斥锁。根据这个链接, pthread_mutex_setpshared符合 POSIX P1003.1c。 (条件变量也是如此,请参阅pthread_condattr_setpshared.)

相关问题:Linux 上的 pthread 条件变量,奇怪的行为

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

共享内存中的条件变量 - 此代码符合 POSIX 标准吗? 的相关文章

  • 在 UNIX 时间戳 Shell/Bash 中将日期与时区转换

    我需要将日期从格式为 yyyy mm dd hh mm ss TZ 的字符串转换为 UNIX 时间 TZ 时区 到目前为止我所做的是将没有时区的 yyyy mm dd hh mm ss 格式的日期转换为时间戳 dateYMD 2019 2
  • 在 bash 函数中生成后台进程

    我正在编写一个 Bash 函数来启动需要从某个文件夹启动的服务器 但我不希望启动该服务器影响我当前的工作 我写了以下内容 function startsrv pushd cd TRUNK SERVERCOMMAND popd 我的变量都已设
  • 将用户添加到组但运行“id”时未反映

    R 创建了一个名为 Staff 的组 我希望能够在不以 sudo 身份启动 R 的情况下更新软件包 所以我使用以下方法将自己添加到员工中 sudo usermod G adm dialout cdrom plugdev lpadmin ad
  • 如何拆分一行并重新排列其元素?

    我在一行中有一些数据 如下所示 abc edf xyz rfg yeg udh 我想呈现如下数据 abc xyz yeg edf rfg udh 以便打印备用字段并用换行符分隔 有没有这样的衬里 下列awk脚本可以做到这一点 gt echo
  • shell 脚本:错误的解释器:使用 pwd 时没有这样的文件或目录

    我想用 for 循环遍历目录中的文件 但这出现了 echo bad interpreter No such file or directory code bin bash count 0 dir pwd echo dir FILES ls
  • Supervisorctl 错误:unix:///var/run/supervisord.sock 拒绝连接? [关闭]

    Closed 这个问题不符合堆栈溢出指南 help closed questions 目前不接受答案 这是我的配置文件 我运行supervisord c etc supervisor supervisord conf效果很好 当我尝试跑步时
  • meld - GLib-GIO-ERROR**:系统上未安装 GSettings 架构

    经过近40个小时的努力 我终于安装了meld 3 14 2 在Redhat 6 3服务器的NFS共享上 安装了每个依赖项 最后似乎成功了 但最后一个错误需要解决 meld 20703 GLib GIO ERROR No GSettings
  • Xenomai 中的周期性线程实时失败

    我正在创建一个周期性线程 它在模拟输出上输出方波信号 我正在使用 Xenomai API 中的 Posix Skin 和 Analogy 我使用示波器测试了代码的实时性能 并查看了方波信号 频率为 1kHz 的延迟 我应该实现 250us
  • shell脚本“x$VARIABLE”中x的用途[重复]

    这个问题在这里已经有答案了 我正在查看一些 shell 脚本 comarison shcu 中 x 的用途是什么 if x USER x RUN AS USER then su RUN AS USER c CATALINA HOME bin
  • linux下如何获取昨天和前天?

    我想在变量中获取 sysdate 1 和 sysdate 2 并回显它 我正在使用下面的查询 它将今天的日期作为输出 bin bash tm date Y d m echo tm 如何获取昨天和前天的日期 这是另一种方法 对于昨天来说 da
  • Python 用静态图像将 mp3 转换为 mp4

    我有x文件包含一个列表mp3我想转换的文件mp3文件至mp4文件带有static png photo 似乎这里唯一的方法是使用ffmpeg但我不知道如何实现它 我编写了脚本来接受输入mp3文件夹和一个 png photo 然后它将创建新文件
  • 在 Unix 中添加用户和组

    有谁知道在unix中添加用户和组以及删除它们的api吗 我想以编程方式执行此操作 谢谢 坦率 我开始查看一些系统调用并发现以下内容 请注意 它们具有不同的标准 因此并非所有标准都可以在您的 Unix 版本上运行 getpwent setpw
  • 在 OSX 和 GNU 中使用“find”删除带有数字的文件名

    我正在尝试搜索一个文件并删除名称中包含数字的类似文件 我的文件 txt from myfile 00 04 version txt myfile 00 txt find E iregex myfile 0 9 1 txt 删除 myfile
  • 为什么总是./configure;制作;进行安装;作为 3 个单独的步骤?

    每次从源代码编译某些内容时 都会经历相同的 3 个步骤 configure make make install 我明白 将安装过程分为不同的步骤是有意义的 但我不明白 为什么这个星球上的每个编码员都必须一次又一次地编写相同的三个命令才能完成
  • Locale.getDefault() 始终返回 en

    unix 机器上的服务器始终使用 en 作为默认区域设置 以下是区域设置输出 LANG en US LC CTYPE C LC NUMERIC C LC TIME C LC COLLATE C LC MONETARY C LC MESSAG
  • 了解多个进程的并发文件写入

    从这里 UNIX 中文件追加是原子的吗 https stackoverflow com questions 1154446 is file append atomic in unix 考虑多个进程打开同一个文件并向其追加内容的情况 O AP
  • 如何执行“sudo nvm”?

    在我的 Mac 上 我想将一些需要 su 权限的包迁移到另一个节点版本 我使用 homebrew 安装 nvm 现在我需要执行 sudo nvm 或 reinstall packages将失败 me MacBook sudo nvm sud
  • awk/Unix 分组依据

    有这个文本文件 name age joe 42 jim 20 bob 15 mike 24 mike 15 mike 54 bob 21 试图得到这个 计数 joe 1 jim 1 bob 2 mike 3 Thanks awk F NR
  • NPTL 和 POSIX 线程有什么区别?

    NPTL 和 POSIX 线程之间的基本区别是什么 这两者是如何演变的 POSIX 线程 pthread 不是一个实现 它是几个函数的 API 规范 纸上的标准 英文 其名称以pthread 以及定义在
  • 如何查看正在运行的 tcsh 版本?

    如何查看我的 UNIX 终端中运行的 tcsh 的当前版本 看着那 这version多变的 echo version tcsh 6 14 00 Astron 2005 03 25 i386 intel linux options wide

随机推荐