Linux System V信号量(互斥操作)

Winema ·
更新时间:2024-11-15
· 920 次阅读

System V信号量:

System V信号量与System V其他两种通信机制(消息队列、共享内存)不同,其用来实现同步、互斥进程动作,通过semget函数创建一个信号集或打开一个信号量集,信号集又包括多个信号量,信号量的值要大于等于0,小于0,就会阻塞。

信号量pv操作:

p操作:操作当前信号量减去某个值
v操作:操作当前信号量加上某个值

一 . semget函数(创建信号量集):

int semget(key_t key, int nsems, int semflg)

1 . key : IPC key
2 .nsems : 信号量个数
3 . semgflg : 信号量集权限

二 . semctl函数(信号量控制):

int semctl(int semid, int semnum, int cmd, union semun arg)

1 .semid:为信号量集标识符
2.semnum:为第几个信号量
3 .cmd:为以下取值:

在这里插入图片描述
在这里插入图片描述
4 .union semun arg : 为以下取值:

union semun { int val; strut semid* buf; unsigned short* array; };

在这里插入图片描述

三 . semop函数:

int semop(int semid, struct sembuf sops, size_t nsops)

1. semid:为信号量集标识符
2. sembuf *sops(可以为结构体数组首地址):为以下取值:

struct sembuf { unsigned short sem_num; short sem_op; short sem_flg; };

在这里插入图片描述
3. nsops:sembuf *sops个数

未互斥计数: #include #include #include #include #include int main() { int pid; int count = 0; pid = fork(); if(pid > 0) { while(count < 1000) { count++; printf("父进程:%d\n",count); } wait(NULL); //等待子进程退出 } else if(pid == 0) { while(count < 1000) { count++; printf("子进程:%d\n",count); } } else if(pid < 0) { printf("fork error\n"); exit(1); } return 0; }

父进程创建出子进程,俩进程各计数到1000,并打印出来,由于未使用信号量实现俩进程互斥,所以父子进程会交替打印。
在这里插入图片描述

信号量互斥计数: #include #include #include #include #include #include #include #include struct sembuf add_sop,cut_sop; union semun { int val; struct semid_ds *buf; unsigned short *array; }; void add_init() { add_sop.sem_num = 0; add_sop.sem_op = 1; //p操作 add_sop.sem_flg = 0; } void cut_init() { cut_sop.sem_num = 0; cut_sop.sem_op = -1; //v操作 add_sop.sem_flg = 0; } int main() { int count = 0;; int semid; union semun arg; int pid; arg.val = 1; add_init(); cut_init(); semid = semget(IPC_PRIVATE,1,IPC_CREAT | S_IRUSR | S_IWUSR); //信号量个数为1 semctl(semid,0,SETVAL,arg); //设置信号量0的值为1 pid = fork(); if(pid > 0) // 父进程 { semop(semid,&cut_sop,1); // 信号量p操作 while(count < 1000) { count++; printf("父进程:%d\n",count); } semop(semid,&add_sop,1); // 信号量v操作 wait(NULL); //等待子进程退出 } else if(pid == 0) //子进程 { semop(semid,&cut_sop,1); // 信号量p操作 while(count < 1000) { count++; printf("子进程:%d\n",count); } semop(semid,&add_sop,1); // 信号量v操作 } else if(pid < 0) { printf("fork error\n"); exit(1); } return 0; }

加入信号量后,俩进程能够实现互斥。一个进程在计数打印,另一个进程p操作就会使信号量小于0,进而阻塞,必须要等待上一个进程计数打印完成后,进行v操作释放信号量,才会解除阻塞。
在这里插入图片描述

ipcs -s : 查看已有信号量集

在这里插入图片描述


作者:哈。。。哈



Linux 互斥 system

需要 登录 后方可回复, 如果你还没有账号请 注册新账号