linux 在POSIX中是否允许复制未命名的信号量?

vmpqdwk3  于 2022-11-02  发布在  Linux
关注(0)|答案(1)|浏览(163)

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的官方文档中找不到任何关于这种行为的描述。

nuypyhwy

nuypyhwy1#

POSIX规范提到:
对于barrier、条件变量、mutex和读写锁,如果进程共享属性设置为PTHREAD_PROCESS_PRIVATE,则只有位于用于初始化它的地址的同步对象才能用于执行同步。在锁定、解锁和删除同步对象时引用同一对象的另一个Map或销毁对象未定义.如果进程共享属性设置为PTHREAD_PROCESS_SHARED,则只有同步对象本身可用于执行同步;但是,不需要在用于初始化它的地址处引用它(也就是说,可以使用同一对象的另一个Map)。在锁定、解锁或销毁对象时引用对象副本的效果未定义
因此,为了符合POSIX标准,不允许复制。

相关问题