【问题标题】:Is it allowed to copy unnamed semaphores in POSIX?是否允许在 POSIX 中复制未命名的信号量?
【发布时间】:2022-11-01 18:43:32
【问题描述】:

POSIX 具有未命名(基于内存)信号量的概念。这些在某个内存位置初始化为sem_init,然后我们可以将它们与sem_postsem_wait 一起使用。我想知道将“信号量句柄”复制到其他内存位置然后将其用作正常、独立、初始化良好的信号量是否总是可以接受的。

换句话说,这样做是否合法:

#include "semaphore.h"

int main()
{
  sem_t s1;
  sem_init(&s1, 0, 1); /* Initialize unnamed semaphore */

  sem_t s2 = s1; /* Copy to some other memory location */
  sem_wait(&s2); /* Lock on the semaphore */
  sem_post(&s2); /* Release the lock */ 
  
  return 0;
}

这似乎在 Linux 上工作得很好,没有问题。在 glibc 中,信号量似乎只是 2 或 3 个整数,使用原子指令来确保它是线程(甚至进程)安全的:https://github.com/bminor/glibc/blob/6c2f050dbe11fb4ed0a401a5f25731f2aa53046b/htl/pt-internal.h#L333 所以,如果我复制信号量,它只会复制它的当前状态(它的值),这很好。

但是,我想知道这是否只是偶然的,我们不能将这种行为依赖于其他 POSIX 实现。

例如,我发现在 FreeRTOS+POSIX 层(https://freertos.org/FreeRTOS-Plus/FreeRTOS_Plus_POSIX/index.html),这是无效的,因为它的信号量是在 FreeRTOS 信号量之上实现的,并且 FreeRTOS 内核会跟踪初始化信号量的地址。因此,不可能只是盲目地将信号量句柄复制到不同的内存位置然后使用它。当然,请注意,FreeRTOS+POSIX 库并未声称与 POSIX 兼容,它仅实现了 POSIX API 的一小部分,因此这只是一个示例。

我在官方 POSIX 文档中找不到任何提及此行为的内容。

【问题讨论】:

    标签: c linux posix semaphore glibc


    【解决方案1】:

    POSIX specification 提到:

    对于屏障、条件变量、互斥锁和读写锁,如果进程共享属性设置为 PTHREAD_PROCESS_PRIVATE,只有用于初始化它的地址处的同步对象才能用于执行同步。在锁定、解锁或销毁对象时引用同一对象的另一个映射的效果未定义.如果 process-shared 属性设置为 PTHREAD_PROCESS_SHARED,则只能使用同步对象本身进行同步;但是,它不需要在用于初始化它的地址处被引用(也就是说,可以使用同一对象的另一个映射)。在锁定、解锁或销毁对象时引用对象副本的效果未定义.

    因此,为了符合 POSIX,不允许复制。

    【讨论】:

      猜你喜欢
      • 2012-08-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2020-03-20
      相关资源
      最近更新 更多