转载自:http://blog.youkuaiyun.com/ADDw1/article/details/61936214?locationNum=2&fps=1
信号量
- 信号量的本质是一种数据操作锁
- 信号量的本质是具有原子性的计数器
- 信号量本身只是一种外部资源的标识
- 信号量本身不具有数据交换的功能,而是通过控制其他的通信资源来实现进程间通信,在此过程中负责数据操作的互斥、同步等功能
原子性
- 两种状态
- 如果把一个事务可看作是一个程序,它要么完整的被执行,要么完全不执行。这种特性就叫原子性
临界资源
- 不同进程共同看到的资源
- 一次仅允许一个进程使用的资源称为临界资源
临界区
- 共同访问临界资源的那份代码
同步
- 以特定顺序访问临界资源
互斥
- 任何时刻,只允许一个进程进入临界区访问临界资源并且属性是原子的
信号量的工作原理
- 信号量只能进行两种操作等待和发送信号,即P(sv)和V(sv)
- P(sv):如果sv的值大于零,就给他减1;如果它的值为零,就挂起该进程的执行
- V(sv):如果有其他进程因等待sv而挂起,就让他恢复运行,如果没有进程因等待sv而挂起,就给他加1
举个例子,就是两个进程共享信号量sv,一旦其中一个进程执行行了P(sv)操作,它将得到信号量,并可以进入入临界区,使sv减1。而第二个进程将被阻止进入临界区,因为当它试图执行P(sv)时,sv为0,它会被挂起以等待第一个进程离开临界区域并执行V(sv)释放信号量,这时第二个进程就可以恢复执行。
转载自:http://blog.youkuaiyun.com/qq_26768741/article/details/55292520
对于信号量来说,是IPC机构当中的一个,与消息队列等不同,它是一个计数器,用于为多个进程提供对共享数据对象的访问,接下来,我们对信号量进行一些探索。
在这我们需要提出一些概念:
临界区:指的是访问临界资源的程序代码片段。临界区只能允许一个进程进入。
临界资源:临界资源说的是一次只能提供一个进程使用的资源。
互斥:互斥是指某一个资源同时只允许一个访问者对其进行访问。
原子性:一个事务包含多个操作,这些操作要么全部执行,要么全都不执行。
加锁:这里的加锁就是给临界区加锁,也叫做互斥锁,用来保护临界区。因为两个进程同时访问临界区会可能出现问题,所以需要互斥锁来保护。
1.使用信号量的原因
经常我们会遇到这种情况,就是可能会出现多个程序同时去访问一个共享资源,这个时候会出现问题,为了防止出现因多个程序同时访问一个共享资源而引发的一系列问题,我们需要一种方法,它可以通过生成并使用令牌来授权,在任一时刻只能有一个执行线程访问代码的临界区域。临界区域是指执行数据更新的代码需要独占式地执行。而信号量就可以提供这样的一种访问机制,让一个临界区同一时间只有一个线程在访问它,也就是说信号量是用来调协进程对共享资源的访问的。信号量具有原子性,最简单的信号量只能取0和1,也叫做二元信号量,可控制单个资源。
程序对信号量的操作是原子性的,只会进行P(等待)操作或者是V(发送)操作,当两个进程在进行对信号量的访问的时候,一个进程运行,一个进程这个时候为休眠状态。
临界区加了互斥锁,所以这个时候申请锁资源,如果申请到了,那么就进入临界区,如果没申请到,那么就挂起。
一个进程获得共享资源,需要执行的操作为:
(1)测试控制该资源的信号量。
(2)若此信号量为正,则进程可以使用该资源。这个时候信号量值减1,表示进程在使用一个资源。
(3)当型号了为0,这个时候进入休眠状态,直到信号量大于0,进程唤醒。
2.信号量的特点
(1)和消息队列一样。信号量也是在内核中实现的,并且信号量是随内核的,也就是当进程结束的时候,信号量是没有被销毁的。
(2)信号量并非单个非负值,而必须定义为含有一个或多个信号量值的集合。当创建信号量的时候,需要指定集合当中信号量值的数量。
(3)信号量的创建和初始化不是原子的,所以这样就会导致出一个问题,由于不互斥,就是可能会出现创建后未初始化就被另外一个进程获取。
3.信号量的操作
信号量只能进行两种操作等待和发送信号,即P和V:
P(sv):如果sv的值大于0,就给它减1,如果它的值为0,就挂起该进程的执行。
V(sv):如果有其他进程因等待sv而被挂起,就让它恢复运行,如果没有进程因等待sv而挂起,就给它加1。