【问题标题】:inter processes shared memory and pthread_barrier: how to be safe?进程间共享内存和pthread_barrier:如何安全?
【发布时间】:2011-05-28 05:31:55
【问题描述】:

我想要一个简单的进程间障碍解决方案。这里有一个解决方案:solution

但是我完全迷失了 mmap...第一次尝试时,它失败了十分之一(段错误或死锁)。

我知道我的问题来自同步问题,但我找不到。我找到了一个设置 mmaped 内存的示例 (example),但我不确定它是否适合 mmaped pthread_barrier。

这里是我的代码摘录:

#define MMAP_FILE "/tmp/mmapped_bigdft.bin"

void init_barrier() {
  pthread_barrier_t *shared_mem_barrier;
  pthread_barrierattr_t barattr;
  pthread_barrierattr_setpshared(&barattr, PTHREAD_PROCESS_SHARED);

  hbcast_fd = open(MMAP_FILE, O_RDWR | O_CREAT | O_TRUNC, (mode_t)0600);
  result = lseek(hbcast_fd, sizeof(pthread_barrier_t)-1, SEEK_SET);
  result = write(hbcast_fd, "", 1);
  shared_mem_barrier = (pthread_barrier_t*) mmap(0, sizeof(pthread_barrier_t), PROT_READ | PROT_WRITE, MAP_SHARED, hbcast_fd, 0);
  if (mpi_rank == 0) {
    int err = pthread_barrier_init(shared_mem_barrier, &barattr, host_size);
  }
  MPI_Barrier(some_communicator);
}

问题:

  • 我错过了 mmap 初始化中的某些内容吗?
  • 哪些操作应由所有进程执行,哪些应仅由一个进程执行?

新问题

管理 pthread 屏障哪个更安全?还是它们基于相同的机制?

  • shmget
  • shm_open
  • mmap
  • 另一个

【问题讨论】:

    标签: c synchronization pthreads mmap


    【解决方案1】:

    正如查尔斯所提到的,看起来截断是什么让你。此外,您应该使用 pthread_barrierattr_init 初始化属性。

    至于另一个问题,只有一个进程应该进行初始化,然后所有进程都应该调用 pthread_barrier_wait(就像使用 MPI 一样)。

    我看到了你的另一个问题,所以我知道你为什么不想使用 MPI。因此,您可能只需要一个 MPI 屏障来初始化您的 pthread 屏障,如下所示:

    if (rank == 0)
    {
      /* Create the shared memory segment, initialise the barrier. */
    }
    MPI_Barrier(communicator);
    if (rank != 0)
    {
      /* Load the shared memory segment, cast it to a pthread_barrier_t* and store.
       * It's already initialised */
    }
    

    【讨论】:

    • 你会使用哪种共享内存方法?
    • 上次我需要做进程间障碍时,我使用了 MPI ;) POSIX 共享内存应该没问题,这就是你已经在使用的。您只需要在正确初始化共享内存之前阻止其他进程访问共享内存。
    • 我的问题是我应该为 pthread_barrier 使用哪种共享内存范例:mmap、shmget 还是另一个?
    • 抱歉,没有正确读取初始代码。我会使用 shm_open。
    【解决方案2】:

    您不想为每个进程都使用 O_TRUNC 打开文件。每次执行此操作时,您都会再次截断文件,并可能使您之前执行的 mmap 操作无效(更改文件大小时对以前 mmap 的影响通常是未定义的)。

    除此之外,我认为您不能在 mmap 内存中拥有信号量并使其正常运行(它可能在某些操作系统平台上,所以我怀疑它通常能保证按您想要的方式运行)。

    您真正想要使用的是共享内存。在“shmget”和“shmat”上学习如何创建和映射共享内存。您可能仍然需要一个文件来传递共享内存 ID,并且您应该小心在应用程序崩溃期间通过注册信号处理程序来释放共享内存 ID。否则,您可能会留下僵尸共享内存分配并超出您的操作系统资源限制。如果您尝试在主线程上创建共享内存段时获得 ENOSPC,您就会知道发生了这种情况。

    【讨论】:

    • 你有解释所有这些的指针吗?你说 mmap 不是 pthread_barrier 的最佳选择。 shmget 更好?你还有别的想法吗?
    【解决方案3】:

    您应该使用shm_open 创建共享段。

    • 参数O_CREAT你 应该能够检测一个进程 是第一个创建细分的人。
    • 只有那个进程应该截断 段到适当的长度,映射它 并初始化屏障。
    • 所有其他检测到他们 不是第一个应该睡一个 同时,大约一秒钟就足够了,然后映射该段。
    • 之后所有进程都可以 屏障的同步。

    【讨论】:

      猜你喜欢
      • 2014-05-08
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2017-05-10
      • 1970-01-01
      • 2023-03-31
      • 1970-01-01
      • 2021-03-26
      相关资源
      最近更新 更多