信号量S是个整数变量,除了初始化以外,只能通过两个标准原子操作:wait()(P操作)和signal()(V操作)来访问。
wait()的定义:
1 wait(s) { 2 while (S<=0) 3 ; //no-operation 4 S--; 5 }
signal()的定义:
1 signal(S) { 2 S++; 3 }
因为这两个是原子操作,因此对信号量整型值的修改必须不可分地执行。即当一个进程修改信号量时,不能有其他进程同时修改同一信号量的值。
信号量通常分为计数信号量和二进制信号量。计数信号量的值域不受限制,为整数;二进制信号
信号量 | 别名 | 值域 |
计数信号量 | 所有整数 | |
二进制信号量 | 互斥锁(mutex) | 0和1 |
可以使用二进制信号量处理多进程的临界问题。设n个进程共享一个信号量mutex,并初始化为1。每个进程的结构:
do { wait(mutex); // 临界区(critical section) signal(mutex); // 剩余区(remainder section) }while(TRUE);
计数信号量可以用来控制访问具有若干个实例的某种资源。该信号量初始化为可用资源的数量。当每个进程需要使用资源时,需要对该信号量执行wait()(P操作)操作,减少信号量的计数。当进程释放资源时,需要对该信号量执行signal()操作,增加信号量的计数。信号量的计数为0时意味着所有资源都被使用,之后所有需要使用资源的进程将会被阻塞,知道计数大于0。
也可以使用信号量解决同步问题。例如,有两个并发进程P1有语句S1,P2有语句S2,假设要求在S1执行完后才执行S2,令P1和P2共享一个共同信号量synch,将其初始化为0,
P1中插入语句:
S1;
signal(synch);
P2中插入语句:
wait(synch);
S2;
以上所定义的信号量也称为自旋锁。自旋锁通常用于多处理器系统中,这样一个线程在一个处理器自旋时,另一个线程可以在另一个处理器上在其临界区执行。
其优点是,进程在等待锁时不进行上下文切换(上下文切换可能需要花费相当长的时间),如果锁的占用时间短,那么自旋锁就有用了;
其缺点是,忙等待(busy waiting)。当一个进程位于其临界区内时,任何其他试图进入临界区的进程都必须在其进入代码中连续地循环。这种连续循环在实际多道程序系统中是个问题,因为这里只有一个处理器为多个进程所共享。忙等待浪费了CPU时钟,而这本可以有效地为其他进程所使用。
原文:http://www.cnblogs.com/keltoy/p/5052503.html