进程间通信(4)-信号量

news/发布时间2024/5/17 15:10:29
Linux 中的信号量通常指的是进程间通信(IPC)中的一种机制,用于实现进程之间的同步和互斥。在 Linux 中,主要有两种类型的信号量:System V 信号量和 POSIX 信号量。

1. System V 信号量

System V 信号量是最早引入 Linux 的一种进程间通信机制,它使用 semget、semctl 和 semop 等函数进行操作。
创建或获取信号量集:int semget(key_t key, int num_sems, int sem_flags);
控制信号量集:int semctl(int semid, int sem_num, int cmd, ...);
对信号量集进行操作:int semop(int semid, struct sembuf *sops, size_t nsops);
 

2. POSIX 信号量

POSIX 信号量是一种较新的信号量实现,它更加简单和易用,并且在使用上更加符合现代编程习惯。
创建或打开信号量:sem_t *sem_open(const char *name, int oflag, mode_t mode, unsigned int value);
关闭信号量:int sem_close(sem_t *sem);
销毁信号量:int sem_unlink(const char *name);
等待(阻塞)信号量:int sem_wait(sem_t *sem);
增加信号量的值:int sem_post(sem_t *sem);
POSIX 信号量更适合于现代的多线程应用程序和多进程应用程序,因为它提供了更简单的接口和更好的可移植性。
 

下面的demo以POSIX信号量举例:

#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <semaphore.h>
#include <fcntl.h>
#include <sys/stat.h>
#include <sys/wait.h>int main() {sem_t *semaphore;// 创建或打开命名信号量semaphore = sem_open("/my_semaphore", O_CREAT | O_EXCL, S_IRUSR | S_IWUSR, 0);if (semaphore == SEM_FAILED) {perror("sem_open");exit(EXIT_FAILURE);}// 创建子进程1:增加信号量的值pid_t pid1 = fork();if (pid1 == -1) {perror("fork");exit(EXIT_FAILURE);} else if (pid1 == 0) { // 子进程1printf("Child Process 1: Incrementing semaphore\n");for(int i = 0; i < 5; i++) {printf("%d seconds before sem_post \n", 5 - i);sleep(1);}sem_post(semaphore); // 增加信号量的值
        exit(EXIT_SUCCESS);}// 创建子进程2:等待信号量的值达到一定条件pid_t pid2 = fork();if (pid2 == -1) {perror("fork");exit(EXIT_FAILURE);} else if (pid2 == 0) { // 子进程2printf("Child Process 2: Waiting for semaphore\n");sem_wait(semaphore); // 等待信号量的值达到一定条件printf("Child Process 2: Semaphore reached, executing operation\n");exit(EXIT_SUCCESS);}// 等待子进程结束
    wait(NULL);wait(NULL);// 关闭和销毁信号量
    sem_close(semaphore);sem_unlink("/my_semaphore");return 0;
}
 

执行结果如下:

0
 

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.ulsteruni.cn/article/15012026.html

如若内容造成侵权/违法违规/事实不符,请联系编程大学网进行投诉反馈email:xxxxxxxx@qq.com,一经查实,立即删除!

相关文章

进程间通信(2)-消息队列

Linux 中的消息队列是一种进程间通信(IPC)机制,允许不同进程之间通过消息进行通信。消息队列中的相关函数:msgget:创建或打开一个消息队列。 函数原型:int msgget(key_t key, int msgflg); 参数: key:消息队列的键值,用于标识消息队列。 msgflg:标志参数,用于指定消…

进程间通信(1)-管道

匿名管道(Anonymous Pipe)和有名管道(Named Pipe,也称为FIFO)是两种不同的进程间通信方式,它们有以下主要区别:命名和使用方式:匿名管道没有名字,只能在具有亲缘关系的进程之间使用,通常是在调用pipe()函数后直接使用,无需其他步骤。 有名管道有一个文件名,它在文件…

异常编译代码分析

异常编译代码分析 https://lowlevelbits.org/compiling-ruby-part-5/ 调用堆栈、堆栈帧和程序计数器 在程序执行期间,机器维护指向正在执行的指令的指针。它被称为程序计数器(或指令指针)。 当调用一个方法时,程序计数器被设置为被调用函数(被调用者)上的第一条指令。一旦…

Flask 框架启动无法改变端口

避坑! 相信大家使用flask框架的时候有时候会出现无法修改启动端口的情况. 在这里一共有两种解决办法(目前发现)1- 如果你使用的是flask Server 方式启动的你的项目的话, 可以Pycharm的环境变量中指定:FLASK_RUN_PORT=[PORT]2- 如果你使用的Python的话, 可以在代码中手动修改端口…

Java软件安装以及环境配置

Java软件安装以及环境配置 一、JDK安装 JDK官网:https://www.oracle.com/java/technologies/downloads/#java8 根据自己的电脑配置,安装对应平台,对应操作系统的JDK。 本人下载的是Windows x64版本的JDK。

defer 延迟调用【GO 基础】

本文通过示例代码讲解了 defer 的用法和值的注意的点。〇、前言 在 Go 语言中,defer 是一种用于延迟调用的关键字。 defer 在 Go 语言中的地位非常重要,它是确保资源正确释放和程序健壮性的关键字。 本文将通过示例对其进行专门的详解。 一、defer 简介 defer 的主要用途是在…