程序間通訊(4)-訊號量

lethe1203發表於2024-04-04
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;
}

執行結果如下:

0

相關文章