用于同步进程的信号量代码示例

注:本文章代码示例以及知识点来自《Linux高性能服务器编程》一书,对应章节13.5——信号量。

一、父、子进程间使用一个IPC_PRIVATE信号量来同步

Linux信号量的API有两组,一组是本文章中所使用的System V IPC信号量,其定义在sys/sem.h头文件中,主要包含3个系统调用:semget、semop、semctl,它们都被设计为操作一组信号量,即信号量集,而不是单个信号。;
另一组是与线程相关的POSIX信号量,其定义在头文件semaphore.h头文件中,具体参考章节14.4——POSIX信号量。

可以结合对比线程同步中的互斥锁来进行学习。

#include <sys/sem.h>
#include <cstdio>
#include <cstdlib>
#include <unistd.h>
#include <sys/wait.h>

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

void pv(int sem_id, int op) 
{
    struct sembuf sem_b;
    sem_b.sem_num = 0;
    sem_b.sem_op = op; 
    sem_b.sem_flg = SEM_UNDO;
    semop(sem_id, &sem_b, 1); 
}

int main(int argc, char *argv[])
{
    int sem_id = semget(IPC_PRIVATE, 1, 0666);

    union semun sem_un;
    sem_un.val = 1;
    semctl(sem_id, 0, SETVAL, sem_un);

    pid_t id = fork();
    if (id < 0)
    {   
        return 1;
    }
    else if (id == 0)
    {
        printf("child try to get binary sem\n");
        pv(sem_id, -1);
        printf("child get the sem and would release it after 5 seconds\n");
        sleep(5);
        pv(sem_id, 1);
        exit(0);
    }
    else
    {
        printf("parent try to get binary sem\n");
        pv(sem_id, -1);
        printf("parent get the sem and would release it after 5 seconds\n");
        sleep(5);
        pv(sem_id, 1);
    }

    waitpid(id, NULL, 0);
    semctl(sem_id, 0, IPC_RMID, sem_un);
    return 0;
}

二、运行结果
在这里插入图片描述

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
下面是一个Linux系统中使用信号量示例代码,该代码使用了semget、semop和semctl函数来实现进程间的同步和互斥。 ```c #include <stdio.h> #include <stdlib.h> #include <unistd.h> #include <sys/types.h> #include <sys/ipc.h> #include <sys/sem.h> #define SEM_KEY 0x1234 // 信号量键值 #define SEM_NUM 0 // 信号量编号 int main() { int semid, pid; struct sembuf sops[2]; // 信号量操作数组 // 创建一个新的信号量集,其中只包含一个信号量 semid = semget(SEM_KEY, 1, IPC_CREAT | 0666); if (semid == -1) { perror("semget"); exit(EXIT_FAILURE); } // 初始化信号量的值为1 if (semctl(semid, SEM_NUM, SETVAL, 1) == -1) { perror("semctl"); exit(EXIT_FAILURE); } // 创建一个子进程 pid = fork(); if (pid == -1) { perror("fork"); exit(EXIT_FAILURE); } if (pid == 0) { // 子进程执行P操作 sops[0].sem_num = SEM_NUM; sops[0].sem_op = -1; sops[0].sem_flg = SEM_UNDO; if (semop(semid, sops, 1) == -1) { perror("semop"); exit(EXIT_FAILURE); } // 子进程打印一句话 printf("Child process is running.\n"); // 子进程执行V操作 sops[0].sem_num = SEM_NUM; sops[0].sem_op = 1; sops[0].sem_flg = SEM_UNDO; if (semop(semid, sops, 1) == -1) { perror("semop"); exit(EXIT_FAILURE); } exit(EXIT_SUCCESS); } else { // 父进程执行P操作 sops[0].sem_num = SEM_NUM; sops[0].sem_op = -1; sops[0].sem_flg = SEM_UNDO; if (semop(semid, sops, 1) == -1) { perror("semop"); exit(EXIT_FAILURE); } // 父进程打印一句话 printf("Parent process is running.\n"); // 父进程执行V操作 sops[0].sem_num = SEM_NUM; sops[0].sem_op = 1; sops[0].sem_flg = SEM_UNDO; if (semop(semid, sops, 1) == -1) { perror("semop"); exit(EXIT_FAILURE); } // 等待子进程结束 if (wait(NULL) == -1) { perror("wait"); exit(EXIT_FAILURE); } // 删除信号量集 if (semctl(semid, 0, IPC_RMID) == -1) { perror("semctl"); exit(EXIT_FAILURE); } exit(EXIT_SUCCESS); } } ``` 该示例代码创建了一个新的信号量集,其中只包含一个信号量,并将该信号量的值初始化为1。然后,它创建了一个子进程和一个父进程,子进程和父进程都对该信号量进行了P操作和V操作,从而实现了进程间的同步和互斥。最后,父进程等待子进程结束,然后删除信号量集。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值