记录学习过程的点点滴滴,存在不足之处望指正。
在操作系统当中,存在着各种线程,进程,而这些东西会公用一些资源,为了避免混乱,则引进了信号量以实现同步和互斥。
同步:即多个进程协同完成某一个操作
互斥:顾名思义,即A在使用某一资源时,B则不能使用该资源,只有当A释放该资源,B才可以使用,反之亦然。
关于信号量实现同步互斥的两个经典问题!
1、生产者--消费者问题:
问题描述:有一群生产者进程和一群消费者进程共享n个缓冲区的资源,当缓冲区没有满时,生产者可以将生产的产品投入进去;当缓冲区非空时,消费者可以将缓冲区的一个资源给取走。
问题分析:首先两个进程对于缓冲区的访问是一个互斥关系,所以可以设置一个信号量控制互斥关系,同时,只有生产者生产之后,消费者才可以消费,顾,生产者和消费者又存在着密切的同步关系
PV操作的实现:设置信号量mutex作为互斥信号量,互斥信号量初值为1,设置full信号量表示当前已放产品的缓冲区数,初值为0,设置empty信号量表示当前未放产品的缓冲区数,初值为n。
semaphore mutex=1;
semaphore empty=n;
semaphore full=0;
produce(){
while(1){
produce an item in nextp;
p(empty);
p(mutex);
add nextp to buffer;
V(mutex);
V(full);
}
}
consumer(){
while(1){
p(full);
p(mutex);
remove an item from buffer;
v(mutex);
v(empty);
consume the item;
}
}
2、读者——写者问题
问题描述:有两者并发的进程,读者和写者,共享一个文件,共享原则如下:
a:读写互斥访问
b:写写互斥访问
c:允许多个读者同时访问
问题分析:只有两组进程,读写和写写存在互斥关系,而读读则是不存在互斥的,所以通过设置信号量来访问,设置一个count来表示当前读者数量,初值为0,设置mutex为互斥信号量,用于保护跟新count时的互斥,设置rw用于保证读写的互斥关系。
int count=0;
semaphor mutex=1;
semaphor rw=1;
write(){
while(1){
p(rw);
writing;
v(rw);
}
}
reader(){
while(1){
p(mutex);
if(count==0);
p(rw);
count++;
v(mutex);
reading;
p(mutex);
count--;
if(count==0)
v(rw);
v(mutex);
}
}
上面的这种算法存在一个问题,由于读的优先级高于写的优先级,当读的进程不断进来累加,会导致写进程一直处于等待,从而“饿死”;所以可以增加一个信号量,设置写的优先级高于读的优先级,这样就可以避免写进程被饿死的悲惨命运
int count=0;
semaphor mutex=1;
semaphor rw=1;
semaphor w=1;
write(){
while(1){
p(w);
p(rw);
writing;
v(rw);
v(w);
}
}
reader(){
while(1){
p(w);
p(mutex);
if(count==0);
p(rw);
count++;
v(mutex);
reading;
p(mutex);
count--;
if(count==0)
v(rw);
v(mutex);
}
}
通过w信号量,在读进程只占用而不释放,这样,当存在写进程的时候,读进程就得等待,只有等到写进程处理并释放w信号量,才允许下一个读进程执行。
Thanks for your reading。