多进程编程- POSIX命名信号量(named semaphore)

POSIX命名信号量是POSIX标准下的一个进程间同步原语,允许多个进程共享同一个信号量,从而实现进程间的同步和通信。这与无名信号量不同,无名信号量主要用于线程之间的同步,而不是进程之间。

命名信号量是“命名”的,因为它们使用特定的名称,这使得不同的进程可以打开并使用相同的信号量。

以下是关于POSIX命名信号量的一些关键点和功能:

  1. 创建/打开: 使用sem_open函数来创建或打开一个已存在的命名信号量。

  2. 关闭: 使用sem_close来关闭一个信号量的引用。这并不会删除该信号量,只是关闭当前进程对其的引用。

  3. 删除: 使用sem_unlink来删除一个命名信号量。它会将信号量标记为删除状态,并在所有进程都关闭了对它的引用后真正删除它。

  4. 增加: sem_post可以用于增加信号量的值。

  5. 减少: sem_waitsem_trywait可以用于减少信号量的值。如果信号量的值为0,sem_wait会阻塞,而sem_trywait会立即返回一个错误。

  6. 查询: 使用sem_getvalue可以查询信号量的当前值。

  7. 持久性: 命名信号量在系统中是持久的,即使没有进程引用它,它仍然存在,直到使用sem_unlink显式删除。

  8. 位置: 命名信号量通常在/dev/shm/run/shm中作为一个文件出现(取决于系统),尽管它们不是真正的文件,但这为诊断和调试提供了便利。

    扫描二维码关注公众号,回复: 16838248 查看本文章

使用场景:

POSIX命名信号量在需要进程间同步或通信的场景中很有用,例如:

  • 一个进程生成数据,而另一个进程消费这些数据。信号量可以用来同步这两个进程,确保数据在被消费之前已经被生成。
  • 限制对共享资源的并发访问,例如一个配置文件或共享数据库。

使用POSIX命名信号量时,应注意避免死锁,并确保在所有情况下都正确地释放已获取的信号量。

#include <stdio.h>
#include <fcntl.h>
#include <sys/stat.h>
#include <semaphore.h>
#define SEM_NAME "namedsem"  // Defines the name of the semaphore

int main()
{
    
    
    sem_t *p_sem = NULL;
    // Create a semaphore
    p_sem = sem_open(SEM_NAME, O_CREAT|O_EXCL, 0666, 0);
    sem_wait(p_sem);        // Wait the sempahore
    sem_unlink(SEM_NAME);   // Delete the semaphore
    return 0;
}

在这里插入图片描述

#include <stdio.h>
#include <fcntl.h>
#include <sys/stat.h>
#include <semaphore.h>
#define SEM_NAME "namedsem"

int main() {
    
    
    sem_t *p_sem = NULL;
    p_sem = sem_open(SEM_NAME, O_RDWR); // Open the semaphore
    sem_post(p_sem);                    // Release semaphore
    return 0;
}

在这里插入图片描述

以上两个程序,它们分别展示了如何使用POSIX命名信号量(named semaphore)。

  1. 第一个程序: 创建并等待信号量

    • 定义了一个命名信号量的名称namedsem
    • 使用sem_open函数,结合O_CREAT|O_EXCL标志,尝试创建并打开一个新的命名信号量。如果该信号量已经存在,调用会失败。
    • 设置的信号量初始值为0,这意味着信号量在创建后不可用。
    • 然后,程序调用sem_wait,尝试获取这个信号量。因为信号量的初始值为0,所以该调用会阻塞,直到有其他进程或线程使用sem_post释放信号量。
    • 最后,它调用sem_unlink来删除命名信号量。但请注意,只有在所有进程都关闭了该信号量的引用后,信号量才会被真正删除。
  2. 第二个程序: 打开并释放信号量

    • 使用相同的命名信号量名称namedsem
    • 使用sem_open函数,结合O_RDWR标志,尝试打开一个已存在的命名信号量。这里不再创建新的信号量,而是打开一个现有的信号量。
    • 然后,调用sem_post来释放这个信号量。这实际上会增加信号量的计数值。如果第一个程序在sem_wait中等待,它现在可以获取信号量并继续执行。

结论:
这两个程序组合起来演示了进程间同步的一个简单场景。第一个程序创建并等待一个信号量,而第二个程序打开这个信号量并释放它,从而允许第一个程序继续执行。这是进程间通信和同步的一个简单但非常有用的例子,它展示了如何使用命名信号量进行协作。

猜你喜欢

转载自blog.csdn.net/weixin_43844521/article/details/133239772
今日推荐