★IPC方法包括管道(PIPE)、消息队列(Message_Queue)、信号量(semaphore)、共用内存
(ShareMemory)以及套接字(Socket)。进程间通信主要包括了管道、系统IPC(包括了消息队列、信号以
及共享存储)、套接字(SOCKET)。此文将探讨信号量机制的相关内容。
★信号量:
信号量不以传输数据为目的,其本质是一种数据操作锁,本身不具有数据交换的功能,而是通过控制其他的通信
资源(例如文件、外设等)来实现进程间通信,只是一种外部资源的标志。信号量在此过程中负责数据操作的互斥,
同步等功能。其建立和初始化的过程不能保证均是基于原子层面的操作。
在此之前,须引出同步和互斥的有关概念。
①临界资源:不同进程访问的同一资源称为临界资源。
②临界区:两个或多个进程访问临界资源的代码称为临界区。
★★★★★★★★★★★★★★★★★★★★★★ 1. 什么是互斥 ★★★★★★★★★★★★★★★★★★★★
多进程环境下,若一个进程已进入临界区访问临界资源时,其他进程不得进入临界区。该进程独自享有临界区全
部临界资源,对于其他进程具有强烈的排斥性。这种只允许一个执行流访问临界资源的情形称为互斥。
★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★
★★★★★★★★★★★★★★★★★★★★★ 2. 什么是同步 ★★★★★★★★★★★★★★★★★★★★
在多执行流访问临界资源时,对某一执行流频繁访问临界资源而长时间享有独占性时,对于较之不频繁访问临
界资源的执行流来说要等待的时间过久,所以互斥虽能保证各进程进入临界区访问临界资源时的数据正确性,但却并
非最高效的方法。所以在互斥基础上,访问临界区的临界资源时各进程产生一定的访问顺序,这种顺序性称为同步。
★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★
⑴表示过程:当请求一个使用信号量来表示的资源时,进程需要先读取信号量的值来判断资源是否可用。大于0,资
源可以请求,等于0,无资源可用,进程会进入睡眠状态直至资源可用。
⑵工作原理:由于信号量只能进行两种操作等待和发送信号,即P(sv)和V(sv)。P(sv):如果sv的值大于
零,就将其减一;如果它的值为零,就挂起该进程的执V(sv):如果有其他进程因等待sv而被挂起,就让它恢复运
行,如果没有进程因等待sv而挂起,就将其加1。
★linux为信号量机制提供了许多关于信号量操作的函数,这些函数用来对成组的信号量进行操作,其声明在头文件
<sys/sem.h>中。
注:从上图可以看出,在sem_structure中也有关于struct_ipc_perm的结构体成员(红框部分),这说明信号量同
样是IPC下的进程间通信方式之一。 注:虽说信号量的本质不具有数据交换的功能,但是其在进程间通信中负责数据
操作的互斥及同步的功能,从这一点上来看,信号量也是进程间通信的一种方式,只是它不像管道,消息队列、共享
内存那样严格。
★在这众多的关于信号量的操作函数中,semctl是比较特殊且尤为重要的函数。
▲semctl()在semid标识的信号量集上,或者该集合的第semnum个信号量上执行cmd指定的控制命令(信号量集合
索引起始于零)。根据cmd不同,这个函数有三个或四个参数。当有四个参数时,第四个参数的类型是union。见下
图(红线部分):
★通过信号量机制的设置让终端的父子进程分别输出A和B字符时交叉显示。
代码:
①comm.h:声明所涉及的函数的接口。
注:可以看到,该文件中不仅定义了semctl函数中的联合体(粘贴过来的),并且还定义了信号量的创建,获取,清
除,初始化及重置,以及P和V操作的接口函数。
②comm.c:对.h文件中声明的函数接口的具体实现。
③test_sem.c:主函数---------->测试用例
④Makefile:程序的自动化编译
注:主函数中用到了usleep控制等待毫秒数量级,sleep输出长串字符太慢,因为要短时看到父子进程输出的字符是
否是按规律先后输出(有无交叉),所以通过usleep缩短时间,其值是随便给的,并无规定。
运行结果: