标签:
进程同步即多个进程中发生的事件存在某种时序关系,需要相互合作,共同完成一项任务。具体来说,一个进程运行到某一点时,需要另一个伙伴进程为它提供信息,在获得消息之前,该进程进入阻塞态,获得消息后被唤醒进入就绪态。
1 生产者/消费者问题
问题描述:
1) 生产者进程生产某种类型数据放置在缓冲区
2) 消费者从缓冲区取数据,每次取一项
3) 只能有一个生产者或者消费者对缓冲区进行操作
要解决的问题:
1) 缓冲区满,生产者不再生产
2) 缓冲区空,消费者不再取
3) 生产与消费不可同时操作
1 #define N 100 2 int count = 0; 3 void producer(void) 4 { 5 int item; 6 while(true) { 7 item = produce_item(); 8 if(count == N) 9 sleep(); 10 insert_item(item); 11 count++; 12 if(count == 1) 13 wake_up(consumer); 14 } 15 } 16 17 void consumer(void) 18 { 19 int item; 20 while(true) { 21 if(count==0) 22 sleep(); 23 item = remove_item(); 24 count--; 25 if(count == N-1) 26 wake_up(producer); 27 consume_item(item); 28 } 29 }
会产生什么问题?
当消费者判读count==0后在进入睡眠之前,被切换下CPU,生产者生产1,为唤醒消费者(未睡眠),直到生产满。之后,两个进程都将处于睡眠状态无法唤醒。
2 信号量及P、V操作
起初是为了解决互斥(二元信号量),之后推广到一般信号量(多值)解决同步。
信号量上只可进行三种操作:初始化、P和V操作。
1 struct semaphore 2 { 3 int count; 4 queueType queue; 5 }; 6 7 P(s) 8 { 9 s.count--; 10 if(s.count < 0) { 11 该进程状态变为阻塞态; 12 将该进程插入到相应等级队列s.queue末尾; 13 重新调度; 14 } 15 } 16 17 Q(s) 18 { 19 s.count++; 20 if(s.count <= 0) 21 { 22 唤醒相应等级等待队列s.queue中的一个进程; 23 改变其状态为就绪态,并将其插入到就绪队列; 24 } 25 }
3 用信号量解决进程互斥
1)分析并发进程的关键活动,划分临界区
2)设置互斥量mutex,初值为1
3)进临界区前P(mutex)
4)出临界区后Q(mutex)
4 用信号量解决生产者/消费者问题
1 #define N 100 2 typedef int semaphore; 3 semaphore mutex = 1; 4 semaphore empty = 100; 5 semaphore full = 0; 6 7 void producer(void) 8 { 9 int item; 10 while(true) { 11 item = produce_item(); 12 P(empty); 13 P(mutex); 14 insert_item(item); 15 V(mutex); 16 V(full); 17 } 18 } 19 20 void consumer(void) 21 { 22 int item; 23 while(true) { 24 P(full); 25 P(mutex); 26 item = remove_item(); 27 V(mutex); 28 V(empty); 29 consume_item(); 30 } 31 }
5 用信号量解决读者/写者问题
问题要求:1) 允许多个读者同时读 2) 不允许多个写者同时写 3) 读写不可同时运行。
第一类读者/写者问题:读者优先
如果读者执行:
1)无其他读者、写者,该读者可读
2)若有写者等待,但有其他读者读,则该读者也可以读
3)若有写者写,则该读者必须等
如果写者执行;
1) 无其他读者、写者,则该写者写
2) 若有读者正在读,该写者等
3) 若有其他写者在写,则等
1 void reader(void) 2 { 3 while(true) { 4 P(mutex); 5 rc++; 6 if(rc==1) 7 P(w); //第一个读者 8 V(mutex); 9 10 读操作 11 12 P(mutex); 13 rc--; 14 if(rc==0) 15 V(w); //最后一个读者 16 V(mutex); 17 } 18 19 } 20 21 void writer(void) 22 { 23 while(true) { 24 P(w); 25 26 写操作 27 28 V(w); 29 } 30 }
标签:
原文地址:http://www.cnblogs.com/darrensun/p/4630009.html