临界区:临界区是指不同的进程中,有可能访问共享变量,操作同一个表或文件的代码段;
临界区问题是指设计一个用于进程间协调的协议。
信号量
信号量S是一个整数变量,除了初始化以外,它只能通过两个标准化原子操作wait和signal访问,这两个操作也被称为P、V操作。信号量主要用于解决进程间共享资源的协调问题;它一般被初始化为资源的数量;当然信号量也可以用于解决进程间同步问题
信号量的实现:
自旋锁(SpinLock):wait操作通过忙等实现,优点是进程等待时不需要上下文切换,对于持有锁时间很短的情况比较适用
wait(S) {
while(S <= 0)
; // no-op
S--;
}
signal(S) {
S++;
}
非忙等实现:
对于wait操作,当进程发现信号量的值不为正时,挂起进程并添加到和该信号量相关的等待队列中;signal操作会唤醒(wakeup)该等待队列中的等待进程
信号量定义:
typedef struct {
int value;
struct process *L;
} semaphore;
void wait(semaphore S) {
S.value--;
if(S.value < 0){
add this process to S.L;
block(); // 挂起当前进程
}
}
void signal(semaphore S){
S.value++;
if(S.value <= 0){
remove a process P from S.L;
wakeup(P); //唤醒进程P
}
}