名称信号量和匿名信号量

16

我正在尝试理解命名信号量和未命名信号量之间的相似之处和区别,所以我的谷歌搜索给我带来了这个。不过我对页面上的措辞有些疑问,它说:

  • 未命名信号量可能被多个进程使用
  • 命名信号量可以被多个进程共享

这两个词是否在这两种类型的信号量之间创建了任何重要的区别,还是它们无关紧要?

到目前为止,这就是我所拥有的:

Similarities
    -Several processes can do something with the semaphore

Difference
    -Named are referenced with pathname and unnamed are referenced by pshared value

那是我能从定义中获取的全部信息。这是全部内容吗?它们正确吗?或者我错过了一些重要的概念?

3个回答

21

考虑谁可以访问信号量。

没有名称或句柄以定位它们的未命名信号量必须存在于某个预先协商的内存位置中。通常情况下,它们是(1)子进程继承的共享内存;或者(2)在同一进程的线程之间共享时,它们是共享内存、全局变量或堆。这里的关键是父进程、子进程或线程中的代码已经知道信号量的地址。

对于无关的进程,需要使用命名信号量。例如,一个生产者和一个消费者可能由两个不同的开发人员编写,并作为完全不相关的进程运行。但是他们必须共享一些需要用信号量保护的资源。 命名信号量给他们提供了一条路径到信号量。

实际上,您可以在所有场景中使用命名信号量,但是它们会带来一些额外的负担,因为您必须处理路径和权限等与程序相关的问题,如果程序已经知道如何访问一个未命名的信号量,这些都是不必要的。例如,在线程之间共享资源时,使用命名信号量有点愚蠢。 线程已经可以访问相同的内存,其中未命名的信号量可以驻留。


12

被接受的答案是错误的(以及由@electron给出的其他答案)。未命名的POSIX信号量可以被不相关的进程使用。您只需将数据结构存储在可被相关进程访问的共享内存中,并将其初始化为共享标志设置为1,如此处所示(从这里 shamelessly copied):

int shm;
sem_t * mutex;

if ((shm = shm_open("myshm", O_RDWR | O_CREAT, S_IRWXU))   0) {
    perror("shm_open");
    exit(1);
}

if (ftruncate(shm, sizeof(sem_t)) < 0 ) {
    perror("ftruncate");
    exit(1);
}

if ((mutex = mmap(NULL, sizeof(sem_t), PROT_READ | PROT_WRITE, MAP_SHARED, shm, 0)) == MAP_FAILED) {
    perror("mmap");
    exit(1);
}

if (sem_init(mutex, 1, 1) < 0) {
    perror("semaphore initialization");
    exit(1);
}

将共享内存映射到其地址空间的另一个进程可以访问相同的信号量并与原始进程进行同步。另请参阅sem_init()的POSIX规范及其Linux man页面


-2

命名信号量文件系统中有一个实际名称,可以被多个不相关的进程 共享

未命名信号量只能由同一进程线程使用。

信号量是使用函数创建的。

                 sem init(ptr_semaphore, flag, initial_value);

在哪里

ptr_semaphore: 信号量指针

flag: 表示共享级别的标志

initial_value: 信号量的初始值

如果您将flag=0传递给sem_init(),则信号量只能由属于创建信号量的进程的线程共享。因此,它将创建未命名信号量

          sem_init(ptr_semaphore,0,initial_value)   //unamed semaphore

传递一个非零值允许其他进程也可以访问信号量。因此,这将导致命名信号量
          sem_init(ptr_semaphore,1,initial_value)   //named semaphore

4
“未命名信号量只能被属于同一进程的线程使用” - 错误的。 - aaa90210

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接