(一)
信号量的本质是一种数据操作锁,它本身不具有数据交换的功能,而是通过控制其他的通信资源(文件,外部设备)来实现进程间通信,它本身只是一种外部资源的标识。信号量在此过程中负责数据操作的互斥、同步等功能。
当请求一个使用信号量来表示的资源时,进程需要先读取信号量的值来判断资源是否可用。当信号量的值大于0时,资源可以请求,等于0,无资源可用,进程会进入睡眠状态直到资源可用。当进程不再使用一个信号量控制的共享资源时,信号量的值+1,对信号量的值进行的增减操作均为原子操作,这是由于信号量主要的作用是维护资源的互斥或多进程的同步访问。而在信号量的创建及初始化上,不能保证操作均为原子性。
为了防止出现因多个程序同时访问一个共享资源而引发的一系列问题,我们需要一种方法,它可以通过生成并使用令牌来授权,在任一时刻只能有一个执行线程访问代码的临界区域。临界区域是指执行数据更新的代码需要独占式地执行。而信号量就可以提供这样的一种访问机制,让一个临界区同一时间只有一个线程在访问它, 也就是说信号量是用来调协进程对共享资源的访问的。
(二)信号量的工作原理
由于信号量只能进行两种操作等待和发送信号,即P(sv)和V(sv):
P(sv):如果sv的值大于零,就对它减一,如果它的值为零,就挂起该执行程序;
V(sv);:如果有其他进程因等待sv而被挂起,就让它恢复运行,如果没有进程因等待sv而挂起,就给它加1;
(三)
key:可以认为是一个端口号,也可以由函数ftok生成。
IPC_CREAT 如果IPC不存在,则创建一个IPC资源,否则打开操作。
IPC_EXCL:只有在共享内存不存在的时候,新的共享内存才建立,否则就产生错误。
如果单独使用IPC_CREAT,XXXget()函数要么返回一个已经存在的共享内存的操作符,要么返回一个新建
的共享内存的标识符。如果将IPC_CREAT和IPC_EXCL标志合起来使用,XXXget()将返回个新建的IPC标识
符;如果该IPC资源已存在,或者返回-1。IPC_EXEL标志本身并没有太大的意义,但是和IPC_CREAT标志
合起来使用可以用来保证所得的对象是新建的,而不是打开已有的对象。
程序如下:
sem.h
sem.c
测试函数:
其运行结果为:
运行结果分析:
由此可见使用信号量实现了互斥锁,两个进程互斥的访问了显示屏。
转载于:https://blog.51cto.com/ab3813/1763931