- 我最近开了几个专栏,诚信互三!
====> |||《算法专栏》::刷题教程来自网站《代码随想录》。|||
====> |||《C++专栏》::记录我学习C++的经历,看完你一定会有收获。|||
====> |||《Linux专栏》::记录我学习Linux的经历,看完你一定会有收获。|||
====> |||《C#专栏》::记录我复习C#的经历,深度理解,查漏补缺,不定期更新。|||
====> |||《计算机网络专栏》::记录我学习计算机网络,看完你一定会有收获。|||
进程间通信(3)信号量
- 临界资源和临界区
- 如何保护临界资源
- 什么是信号量
- 信号量的接口
临界资源和临界区
我们首先要理解,什么时临界资源,临界区呢?
1).临界资源是被保护起来的资源。
2).临界区就是访问临界资源的代码。
那么共享内存是临界资源吗?答案是不是,因为普通的共享内存并没有被保护起来。
那么我们如何对共享资源进行保护呢?
如何保护临界资源
保护一个临界资源,我们无外乎要做到两点,1.同步,2.互斥。
1).同步:同步保证了进程访问临界资源有一定的顺序。
2).互斥:互斥保证了在同一时间只有一个进程访问临界资源。
只要满足上述两点,就能保证各个进程对临界资源的写入和读出,都是合法有序的。
那么我们如何保护临界资源呢,我们可以通过信号量。
什么是信号量
信号量是IPC资源,信号量可以理解为一个计数器,在某个进程要访问临界资源时,需要先申请信号量,预留资源。
在操作系统中,将申请信号量的操作称为P操作, 释放信号量被称为V操作。
对于一块资源,我们可以将其分成多份,让每一份都满足互斥和同步,这样对于一块临界资源,我们就可以实现并发访问了。
要实现互斥,则一个信号量就足够了。
若要实现同步,则需要给每个小空间都分配一个信号量。
所以信号量就是实现同步和互斥,从而保护临界资源。
而信号量之所以属于进程间通信,这是因为对于多个要访问临界资源的进程,首先要申请信号量,要申请信号量,则要保证进程们可以看到同一份资源,所以信号量不能由任意通信的进程单方提供,最好由操作系统提供,并且信号量要满足原子性。
信号量的接口
信号量的接口和共享内存十分相似。
1).semget接口申请信号量。
1).参数key,和共享内存一样,也是提供ftok函数生成一个key,同时该key值也是操作系统用于识别唯一的信号量的值。
2).参数nsems,用户创建的信号量的个数。
3).参数semflg,也同共享内存一样,有两个选项,详情可以去看共享内存那篇文章。
该接口返回值为信号量集标识符,可以表示一个信号量,如果申请失败,返回-1。
2).semctl接口控制信号量
1).参数semid,表示对哪一个信号量进行控制。
2).参数semnum,代表对该信号量中的哪一个信号量进行操作,因为返回的信号量标识符代表某个信号量集,这就代表该信号量集中有很多信号量。
3).参数cmd,和共享内存的shmctl的cmd参数相同。
返回值成功返回0,失败返回-1。
3).semop接口操作某个信号量
1).参数semid,表示对哪一个信号量进行操作。
2).参数sops,是一个结构体,并且是一个返回参数,可以让我们获得信号量的属性。
3).参数nsops,表示要对该信号量集中的那个信号量操作。
返回值如果成功返回0,失败返回-1。