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; }