信号量---实现同步互斥

前言

了解信号量之前,要先了解临界资源、同步与互斥的概念
1.临界资源:在同一时间只能被一个进程调用的资源,也称互斥资源
2.同步:保证访问的时序可控性,使调用资源的的顺序合理。
3.互斥:在进程调用临界资源是,不同进程之间要竞争该资源,那么一个进程调用了该资源,另一个进程无法再调用该资源的情形就叫互斥!
4.临界区:代码中涉及到了操作临界资源的代码段叫临界区。
5.原子操作:该操作无法被打断
6.同步与互斥的作用:使访问临界资源时,具有安全性。

信号量

1.实质:
具有一个等待队列的计数器,也属于临界资源的一种,要获取信号量资源,则对信号量进行-1操作,要释放信号量资源,则对信号量资源进行+1操作。
注:信号量操作是原子操作

2.信号量实现同步
原理:进程获取临界资源之前,要先获取信号量资源;
若无信号量资源,则该进程阻塞等待,进入等待队列。
若有信号量资源,则对信号量进行P(-1)操作,再获取临界资源。
当临界资源+1时,对应的信号量资源则执行V(+1)操作,然后唤醒在等待队列中等待获取临界资源的进程。
实现代码:https://gitee.com/free_xin/codes/gdof7qb2y58mr4p9alj1u98(代码过长,博客不易展示)

结果展示:
信号量---实现同步互斥_第1张图片

3.信号量实现互斥
原理:一个进程获取了该临界资源之后,另一个进程无法再访问该临界资源。
实现互斥,采用一元信号量,即:该信号量的计数器,只能为0或1。
一个进程要获取临界资源时,先获取对应的信号量资源;
当无信号量资源时,则该进程阻塞等待,进入等待队列。
当有信号量资源时,则对该信号量资源进行P(-1)操作,然后获取该临界资源。
当该进程使用完临界资源时,将释放信号量资源(对信号量资源进行V(+1)操作),然后唤醒等待队列中的进程。
实现代码:https://gitee.com/free_xin/codes/gdof7qb2y58mr4p9alj1u98(代码过长,博客不易展示)

结果展示:
在这里插入图片描述

4.创建信号量集(信号量的一个集合,一个数组)
int semget(key_t key, int nsems, int semflg);
key:该信号量集的标识符(名字)
nsems:信号量集中信号量的个数
semflg:标志位(IPC_CREST|0644)
成功返回该信号量集的标识码,失败返回-1

5.初始化信号量的计数值
int semctl(int semid, int semnum, int cmd, …[union semun]);
semid:该信号量集的标识码
semnum:信号量集中的信号量的索引(下标、序号)
cmd:将要采取的动作
…:不定参数,是semun联合体,用来传递给cmd的参数
成功返回0,失败-1
注:初始值只能设置一次

cmd选项:
SETVAL:设置信号量集中一个信号量的初始计数值,其值是union semun.val的值,此时需要第四个不定参数选项。
SETALL:设置信号量集中所有信号量的初始计数值。
IPC_RMID:用于删除该信号量集,不需要不定参数。
GETVAL:用于获取该信号量集中一个信号量的计数值。

semun联合体:
信号量---实现同步互斥_第2张图片

6.访问信号量资源(对其进行+1/-1操作)
int semop(int semid, struct sembuf sops, unsigned nsops);*
semid:该信号量集的操作句柄
sops:用来操作信号量进行+1/-1操作的结构体的指针
nsops:信号量的个数
成功返回0,失败返回-1

信号量+1/-1操作的结构体:
信号量---实现同步互斥_第3张图片

7.删除信号量集资源
semctl中cmd选项为IPC_RMID,即删除信号量集资源。

其删除实质类似于共享内存的删除,大家可以参考:https://blog.csdn.net/Code_ZX/article/details/85003916

8.信号量集的命令操作
ipcs -s:查看
ipcrm -s +semid:删除semid为semid的信号量集资源
ipcrm -S +key:删除为key的信号量集资源

关于进程的其他内容,大家可以访问主页!!
请多多指教!!
信号量---实现同步互斥_第4张图片

你可能感兴趣的:(学习笔记)