进程--信号量

信号量是什么

资源的竞争

资源竞争 : 当多个进程同时访问共享资源时,会产生资源竞争,最终最导致数据混乱
临界资源 : 不允许同时有多个进程访问的资源,包括硬件资源(CPU、内存、存储器以及其他外围设备)与软件资源(共享代码段、共享数据结构)
临界区 : 访问临界资源代码

可以理解为,狼多肉少,假如有5个人要喝水,但只有一个杯子,为了不让他们打起来,你设定了规则,指到谁,谁才能喝水

信号量: 由内核维护的整数,其值被限制为大于或等于0
信号量可以执行如下操作:
将信号量设置成一个具体的值
在信号量当前值的基础上加上一个数值
在信号量当前值的基础上减上一个数值

等待信号量的值为 0;
一般信号量分为 二值信号量 与 计数信号量
二值信号量:一般指的是信号量的值为1,可以理解为只对应一个资源
计数信号量:一般指的是值大于等于2 ,可以理解为对应多个资源

在 Linux 系统中查询信号量使用 ipcs -s

可以理解为二维数组

创建信号量集合

创建信号量集合调用 semget 函数

函数原型
int semget(key_t key, int nsems, int semflg);

key:由ftok()函数生成
nsems:信号量的数量
semflg:信号量集合的标志
 IPC_CREAT:创建标志
 IPC_EXCL:与IPC_CREAT标志一起使用,如果信号量集合存在就报错
 权限标志
 
函数返回值
成功:返回信号量集合的id
失败:-1,并设置errno

创建后,需要初始化信号量集合

初始化信号量调用 semctl 函数

int semctl(int semid, int semnum, int cmd, …);

semid:信号量集合的id
semnum:信号量的编号,信号量的编号从0开始

cmd:命令控制字

注意:使用命令时需要使用 union semun 共用体,可在man 手册查看

union semun sem;
        key_t key = ftok(SEM_PATHNAME,SEM_PROJ_ID);
        if(key == -1)
       {
                perror("ftok");
                exit(EXIT_FAILURE);
       }
        int semid = semget(key,1,IPC_CREAT|0644);
        if(semid == -1)
       {
                perror("semget");
                exit(EXIT_FAILURE);
       }
        printf("semid = %d\n",semid);
        sem.val = 1;
        int ret = semctl(semid,0,SETVAL,sem);
        if(ret == -1)
       {
                perror("semctl");
                exit(EXIT_FAILURE);
       }

信号量操作

信号量可以进行以下操作:
对信号量的值加1
对信号量的值减1
等待信号量的值为0

操作信号量调用 semop 函数

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

semid:信号量集合id

sops:信号量操作结构体指针

nsops:操作的信号量的数量

struct sembuf 结构体

sements of this structure are of type struct sembuf, containing the following 
members:
unsigned short sem_num; /* semaphore number */
short         sem_op;   /* semaphore operation */
short         sem_flg; /* operation flags */

删除信号量集合

信号量集合调用 semctl 函数,设置命令为 IPC_RMID

int semctl(int semid, int semnum, int cmd, ...);

一般删除 semctl(semid,0,IPC_RMID,NULL);

信号量互斥

通过创建一个信号量集合,包含 2个信号量,一个信号量编号为 0 (SEM_CONTROL_P)控制父进
程的运行与暂停,一个信号量编号为1(SEM_CONTROL_C) 控制子进程的运行与暂停

信号初始化
SEM_CONTROL_P : 初始化为 0
SEM_CONTROL_C : 初始化为 1
子进程
占用 SEM_CONTROL_C ,此时子进程阻塞
当父进程释放 SEM_CONTROL_C 时, 子进程输出 B ,释放 SEM_CONTROL_P
循环占用 SEM_CONTROL_C,由于之前已经占用,此时进入子进程阻塞,等待父进程释放 
SEM_CONTROL_C
父进程
占用 SEM_CONTROL_P,此时父进程正常运行,输出 A
释放 SEM_CONTROL_C,占用 SME_CONTROL_P,此时父进程阻塞,子进程继续执行
当子进程输出 B 之后,释放 SEM_CONTROL_P,父进程继续执行,输出 A

父进程 释放 SEM_CONTROL_P 循环结束

可以理解为,两个信号量的集合,一个值为一,一个为0(集合默认从0开始编号)

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值