信号量机制是由dijkstra 1965年提出,是解决进程同步重要的工具
下面方法适用与几个进程访问同一个临界区
定义一个表示资源数目的整形信号量S,仅能同步P, V操作改变。原始值S=1,每一个进程来的时候会执行:
wait(S) {
while(S <= 0);//资源如果小余0就会阻塞。一直在这边检测
S--;//进入临界区就会将
}
signal(S) {
S ++;//在临界区执行完了,就会把信号量+1
}
整形信号量没有遵循”让权等待原则”,进程一但进不去临界区就在那一直检测,不释放处理机,所以有了记录型信号量
信号量S是一个结构
typedef struct {
int value;//表示资源数目的整形变量
struct process_control_block *list;//进程链表,阻塞的进程都会放到这里
}
wait(semaphore *S) {
S->value--;//首先执行wait操作,就将value-1,
if(S->value < 0) bolck(S->list);//如果发现value小于0,就会阻塞,把进程放入链表中
}
signal(semaphore *S) {
S->value ++;//让value+1
if(S->value <= 0) wakeup(S->list);//如果发现还是小于0,证明还有进程在阻塞,唤醒链表中的第一个进程
}
下面是针对多个并发进程访问多个临界资源
AND型信号量思想,就是把进程整个运行中需要的资源,一次性的全部分配给他,然后进程执行完了,再一次性释放。如果有一个未分配,其他资源也不分配给这个进程,这样就可以避免死锁问题
Swait(S1, S2,.........Sn) {
while(true) {
if(S1>=1&&....&&Sn>=1) {//检测所有的资源都可以分配
for(i = i; i<n; i++) {
for(i = i; i<n; i++) Si--;//所有的资源数量-1
break;
}
}
else {
//进入阻塞队列,等待资源
}
}
}
Ssignal(S1, S2,......Sn) {
while(true) {
for(i=1; i<n;i++) {//释放所有的资源
Si++;
//唤醒等待队列中的进程
}
}
}
上面的只能对信号量执行+1或者-1操作,每次只能对资源进行一个单位的申请或者释放,当需要N个单位的时候,就要执行N此wait操作,这样很低效
机遇AND型信号量的扩充—>信号量集
Swait(S1, t1, d1,.........Sn, tn, dn) {
while(true) {
if(S1>=t1&&....&&Sn>=tn) {//检测所有的资源都可以分配
for(i = i; i<n; i++) {
for(i = i; i<n; i++) Si = Si - di;//所有的资源数量d1,所需的资源量
break;
}
}
else {
//进入阻塞队列,等待资源
}
}
}
Ssignal(S1, d1,......Sn, dn) {
while(true) {
for(i=1; i<n;i++) {//释放所有的资源
Si = Si + di;
//唤醒等待队列中的进程
}
}
}
原文地址:http://blog.csdn.net/ttf1993/article/details/46278639