下面是一个使用信号量函数实现父子进程同步的示例代码:

#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <sys/types.h>
#include <sys/ipc.h>
#include <sys/sem.h>

#define SEM_KEY 1234

union semun {
    int val;
    struct semid_ds *buf;
    unsigned short *array;
};

int main(int argc, char **argv) {
    int sem_id, pid, i;
    union semun sem_arg;
    struct sembuf sem_op;

    // 创建一个信号量集合
    sem_id = semget(SEM_KEY, 1, IPC_CREAT | 0666);
    if (sem_id == -1) {
        perror("semget");
        exit(EXIT_FAILURE);
    }

    // 初始化信号量为1,表示父进程先执行
    sem_arg.val = 1;
    if (semctl(sem_id, 0, SETVAL, sem_arg) == -1) {
        perror("semctl");
        exit(EXIT_FAILURE);
    }

    // 创建子进程
    pid = fork();
    if (pid == -1) {
        perror("fork");
        exit(EXIT_FAILURE);
    }

    if (pid == 0) {  // 子进程
        for (i = 0; i < 5; i++) {
            // 等待信号量为1,表示轮到自己执行
            sem_op.sem_num = 0;
            sem_op.sem_op = -1;
            sem_op.sem_flg = 0;
            if (semop(sem_id, &sem_op, 1) == -1) {
                perror("semop");
                exit(EXIT_FAILURE);
            }

            printf("Child process %d\n", i);

            // 释放信号量,让父进程执行
            sem_op.sem_num = 0;
            sem_op.sem_op = 1;
            sem_op.sem_flg = 0;
            if (semop(sem_id, &sem_op, 1) == -1) {
                perror("semop");
                exit(EXIT_FAILURE);
            }
        }
    } else {  // 父进程
        for (i = 0; i < 5; i++) {
            // 等待信号量为1,表示轮到自己执行
            sem_op.sem_num = 0;
            sem_op.sem_op = -1;
            sem_op.sem_flg = 0;
            if (semop(sem_id, &sem_op, 1) == -1) {
                perror("semop");
                exit(EXIT_FAILURE);
            }

            printf("Parent process %d\n", i);

            // 释放信号量,让子进程执行
            sem_op.sem_num = 0;
            sem_op.sem_op = 1;
            sem_op.sem_flg = 0;
            if (semop(sem_id, &sem_op, 1) == -1) {
                perror("semop");
                exit(EXIT_FAILURE);
            }
        }
    }

    // 删除信号量集合
    if (semctl(sem_id, 0, IPC_RMID, sem_arg) == -1) {
        perror("semctl");
        exit(EXIT_FAILURE);
    }

    return 0;
}

在上面的代码中,父进程和子进程都会通过信号量来控制自己的执行顺序。在信号量初始化时,我们将其值设为1,表示父进程先执行。然后,父进程和子进程都会进入一个循环,在循环体内等待信号量值为1,表示轮到自己执行,然后执行自己的任务。在任务执行完毕后,释放信号量,让另一个进程执行。

通过这种方式,我们可以保证父子进程交替执行,避免了他们之间的竞争条件,从而保证了程序的正确性


原文地址: https://www.cveoy.top/t/topic/chhC 著作权归作者所有。请勿转载和采集!

免费AI点我,无需注册和登录