进程间通信(4)-信号量
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) { // 子进程1 printf("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) { // 子进程2 printf("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; }