📟作者主页:慢热的陕西人
🌴专栏链接:Linux
📣欢迎各位大佬👍点赞🔥关注🚓收藏,🍉留言
本博客主要内容感性认识了信号量,并且认识了IPC资源在操作系统内部是如何组织的
文章目录
- Linux信号量
- 1.互斥等四个概念
- 2.认识信号量
- 3.相关接口的认识
- 3.1semget
- 3.2ipcs -s
- 3.3semctl
- 3.4semop
- 4.理解IPC
- 4.1IPC资源是在内核中如何被组织和管理
Linux信号量
1.互斥等四个概念
首先我们进程通信的基础就是,让进程看到一个共同的资源:公共资源。
a.互斥
任何一个时刻,只允许一个执行流进行在共享资源的访问 – 加锁
b.临界资源
我们把任何时刻,只允许一个执行流访问的共享资源称为临界资源。
c.临界区
临界资源是要通过代码访问的,那么访问临界资源的代码就被称为临界区
d.原子性
要么不做,要么做完,只有两种确定状态的属性,原子性
2.认识信号量
任何技术都是有自己的应用场景的,首先我们通过一个买电影票的场景来感性的认识信号量。
首先我们看电影之前,我们都会先买票。
那么买票的本质功能:
- 对座位资源的预定机制
- 不会因为多方出去特定的座位资源,而导致冲突
那么放映厅是顶级的VIP放映厅,只有一个座位,那么同一时刻只有一个人能进行观看,并且他在观看的时候,其他人是不能去观看的,所以这就相当于我们之前所提到的互斥。
其实信号量本质就是一个计数器:用于描述资源数量的计数器
count
在操作系统内部,任何一个执行流,向访问临界资源中的一个子资源的时候,不能直接访问。要先申请信号量资源,那么我们对应的信号量(count–),只要我们信号量成功,我就一定在未来能拿到一个子资源,叫做我们的申请临界资源成功(也有对应的申请失败,这时候进程就会阻塞挂起)。P操作
当我们的执行流进入自己的临界区,访问对应的临界资源
释放信号量资源 — 对应的信号量(count++) ---- 只要将计数器增加,就代表我们将对应的资源进行了归还。V操作
我们所有使用信号量的进程都是需要保证先看到信号量,那么信号量本质是一种共享资源,所以我们必须保证我们的
count++
和count--
是原子的!总结下来,就是如下一幅图:进程通过执行代码来申请信号量
如何让两个进程看到同一个计数器(count)?
这个需求是不是非常类似于我们进程通信的前提要求,让不同的进程看到同一份资源。
所以信号量被归类到了进程间通信。
假如信号量被设置为1呢?
相当于这一份资源被独立使用了,也就是信号量的互斥功能。
3.相关接口的认识
3.1semget
用于获取信号量
参数:
- key:和我们当时共享内存哪里的含义是一样的,用于操作系统区分对应的信号量;
- nsems:用于表明申请信号量的个数;
- semflg:和共享内存哪里的含义相同,可以输入对应的
IPC_CREAT
,IPC_EXCL
等;
3.2ipcs -s
用于查看当前系统中存在的信号量:我们这时候是没有的所以它没有任何显示
3.3semctl
用于删除信号量的操作
- semid:用户层面用于区分对应的信号量的的标识符;
- semnum:要删除的信号量的个数;
- cmd:要进行的操作;
- …:可变参数
对应的一些相关的结构体:
3.4semop
对对应的信号量做操作
参数:
- semid:表示我们要对哪一个信号量做操作
- *sop:是一个结构体,需要我们去显式的定义具体包含如下的成员:
- nsops:相当于是我们对应信号量数组的下标
4.理解IPC
4.1IPC资源是在内核中如何被组织和管理
那么首先我们操作系统内部都是进行,先描述再组织;
先描述:讲共享内存,信号量,消息队列都用结构体描述起来。
再组织:操作系统用数组将这些对象组织起来
所以在操作系统内核所有的IPC资源都是以数组的方式进行管理的。
那么我们是如何进行访问的:
首先我们进入
ipc_id_arr[]
数组内部,这个数组中全部存储的是struct ipc_perm*
,假设这里我们要访问的是shmid_ds
:那么我们就先将这个指针强转成对应的类型:((struct shmid_ds*)ipc_id_arr[n])->other...
以上的过程其实就是我们的多态,我们对应的
stuct ipc_perm perm
就是基类,那么对应的
struct shmid_ds
,struct semid_ds
和struct msqid_ds
就是子类。所以操作系统内部用不同的指针指向不同的对象,指向谁就访问谁。
到这本篇博客的内容就到此结束了。
如果觉得本篇博客内容对你有所帮助的话,可以点赞,收藏,顺便关注一下!
如果文章内容有错误,欢迎在评论区指正