1200字范文,内容丰富有趣,写作的好帮手!
1200字范文 > Linux进程间通信第四讲 标准IPC之信号量集

Linux进程间通信第四讲 标准IPC之信号量集

时间:2024-03-15 13:21:19

相关推荐

Linux进程间通信第四讲 标准IPC之信号量集

目录

4.3信号量集

4.3.1 概念和原理

4.3.2 使用

4.3信号量集

4.3.1 概念和原理

(不是用于进程间传递数据、而是用于进程间访问控制)

信号量集是一个信号量的集合,可以存放多个信号量

而信号量就是一个计数器,用于记录进程的访问次数, 每来一个进程访问计数值-1(P操作),每离开一个进程计数值+1(V操作)

当计数值为0时就不在允许进程访问,直到计数值重新大于0为止才能允许

那什么时候用到这个呢?

之前在共享内存后面我提到一个问题

如果对于同一个资源, 一个进程对它写, 同时另一个进程又对它读

这会乱 !!!

因此才需要进程的互斥和同步解决上述遇到的问题

而进程的互斥和同步就是用到了信号量集

下面来看下它如何使用吧

4.3.2 使用

1)ftok获取key

2)通过key创建/获取信号量集 ------- semget

参数:

key - 上一步获取的key

nsems - 信号量集中信号量的个数(信号量集的长度)

semflg - 创建标志和权限

IPC_CREAT|0666

3)如果是创建需要设置信号量集中信号量的初始计数 ----- semctl

semctl(信号量集ID,信号量在信号量集中的下标,SETVAL,初始计数值);

4)对信号量进行P-V操作 ------ semop

参数:

semid - 信号量集的ID

sops - 信号量操作数组首地址

nsops - 信号量操作数组的元素个数

成功返回0,失败返回-1

struct sembuf结构体中包含以下成员:unsigned short sem_num; /* 信号量的下标 */shortsem_op; /* 操作方式 -1 / 1 */shortsem_flg; /* 等待方式: 0:阻塞方式 IPC_NOWAIT:非阻塞方式*/

5)不再使用可以删除 -------- semctl

进程1创建共享内存, 因为要和进程2访问同一个资源所以再创建一个信号量集,进程1的代码如下:(进程的互斥)

#include <stdio.h>#include <stdlib.h>#include <string.h>#include <unistd.h>#include <sys/ipc.h>#include <sys/shm.h>#include <sys/sem.h>#include <signal.h>void *p = NULL;int shmid,semid;void func(int sig){shmdt(p);shmctl(shmid,IPC_RMID,0);exit(0);}int main(){char buf[100] = {};signal(SIGINT,func);//1.获取keykey_t key = ftok(".",'x');if(key==-1){perror("ftok");exit(-1);}//2.创建共享内存shmid = shmget(key,100,IPC_CREAT|0666);if(shmid==-1){perror("shmget");exit(-1);}//3.映射共享内存p = shmat(shmid,0,0);if(p==(void *)-1){perror("shmat");exit(-1);}//4.创建信号量集semid = semget(key,1,IPC_CREAT|0666);if(semid==-1){perror("semget");exit(-1);}//5.设置信号量初始值1int res = semctl(semid,0,SETVAL,1);if(res==-1){perror("semctl");exit(-1);}while(1){//P操作, 信号量-1struct sembuf sem;sem.sem_num = 0;sem.sem_op = -1;sem.sem_flg = 0;semop(semid,&sem,1);//写共享内存,发送printf("请输入:");fgets(buf,sizeof(buf),stdin);buf[strlen(buf)-1] = 0;strcpy((char *)p,buf);//V操作,信号量+1sem.sem_op = 1;semop(semid,&sem,1);}return 0;}

进程2的代码如下:(进程的互斥)

#include <stdio.h>#include <stdlib.h>#include <string.h>#include <unistd.h>#include <sys/ipc.h>#include <sys/shm.h>#include <sys/sem.h>#include <signal.h>void *p = NULL;int shmid,semid;void func(int sig){shmdt(p);semctl(semid,0,IPC_RMID);exit(0);}int main(){signal(SIGINT,func);//1.获取keykey_t key = ftok(".",'x');if(key==-1){perror("ftok");exit(-1);}//2.共享内存shmid = shmget(key,0,0);if(shmid==-1){perror("shmget");exit(-1);}//3.映射共享内存p = shmat(shmid,0,0);if(p==(void *)-1){perror("shmat");exit(-1);}//4.信号量集semid = semget(key,0,0);if(semid==-1){perror("semget");exit(-1);}while(1){//P操作, 信号量-1struct sembuf sem;sem.sem_num = 0;sem.sem_op = -1;sem.sem_flg = 0;semop(semid,&sem,1);printf("%s\n",(char *)p);//V操作,信号量+1sem.sem_op = 1;semop(semid,&sem,1);}return 0;}

本内容不代表本网观点和政治立场,如有侵犯你的权益请联系我们处理。
网友评论
网友评论仅供其表达个人看法,并不表明网站立场。