同步问题

对于进程这块来说,同步问题算是一个大头了,我也是看了好几遍,真的服


王道里面这样说:“如果一个操作想要取得资源你就在它前面P一下那个资源,如果一个操作产生了一个资源后,你就要在它后面V一下”;

这个确实,
申请资源之前看看,有没有资源取得,有的话自然进入下一步,没有的话,阻塞了;
生产了资源的,生产了之后V一下,这个时候上面阻塞的那个P就可以继续执行下去了(这也是所谓的唤醒);

几个经典的问题


  • 生产者/消费者
    这里面就有两个进程,producer()、consumer();
    一个产生资源,一个取资源,还有一个用来放资源的缓冲区n个空间;
semaphore mutex=1;
semaphore empty=n;
semaphore full=0;
producer(){
      while(1){
            p(empty);
               p(mutex);
              ...produce
               v(mutex);
             v(full);
       }
}
consumer(){
      while(1){
          p(full);
            p(mutex);
           ...consume;
            v(mutex);
          v(empty);
      }
}

这个里面为啥要用互斥呢!mutex
因为对缓冲区的访问得互斥,同一时刻只可以有一个进程对缓冲区操作;
同步嘛
因为每次生产总要看看缓冲区满没满吧,缓冲区满了就不能在放了(阻塞),或者缓冲区是不是被取空了,空了也不能再取了(阻塞);

  • 多角色消费者问题
    生产者 父亲/母亲 消费者 儿子/女儿
    父亲放苹果/母亲放橘子 儿子吃橘子/女儿吃苹果

这里涉及到四个进程,父亲/母亲/儿子/女儿 ,同时盘子作为一个互斥访问的临界区

semaphore plate=1;
semaphore apple=0;
semaphore orange=0;
dad(){
  while(1){
    prepare an apple;
      p(plate);
        put an apple;
      v(apple);
}
}
mom(){
  while(1){
    prepare an orange;
      p(plate);
        put an orange;
      v(orange);
}
}
son(){
  while(1){
    p(orange);
      take the apple;
    v(plate);
    eat;
}
}
daughter(){
  while(1){
     p(apple);
      take the apple;
     v(plate);
    eat;
}
}

这里面的情况其实比较简单因为儿子和女儿使用的资源不同所以他们之间不存在竞争资源的问题,而作为放水果的父亲母亲对盘子的访问就要互斥进行;

  • 读者写者问题
    总共有两组进程,读者/写者,对同一个文件进行读写,要求有读者在读的时候,不可以进行写操作,但可以有另外的读者同时对该文件读取,也就是说,读写进程不可并发,读进程之间可以并发。
    第一种对于写者并不友好的方式
semaphore count=0;
semaphore mutex=1;
semaphore rw=1;
writer(){
  while(1){
    p(rw);
      write the file;
    v(rw);
  }
}
reader(){
  while(1){
    p(mutex);
      if(count==0)
      p(rw);
      count++;
    v(mutex);
read the file;
    p(mutex);
      count--;
      if(count==0)
      v(rw);
    v(mutex);
}
}

这种情况下,很容易出现有一个稳定读者而使写进程始终都不到处理机,从而出现饥饿现象。下面是一个相对来说比较公平的改进,在这个基础之上加上对访问顺序的控制,
即如果进程有写请求后会将此写进程之后的所有读请求阻塞,使之排在该写进程后面,说白了,所有人 都给我按顺序排好队,没有人有特权;

semaphore w=1;
semaphore rw=1;
semaphore mutex=1;
semaphore count=0;
writer(){
  while(1){
    p(w);
      p(rw);
      write the file;
      v(rw);
    v(w);
}
}
reader(){
while(1){
    p(w);
       p(mutex);
        if(count==0)
        p(rw);
          count++;
        v(mutex);
    v(w);
      read the file;
    p(mutex);
      count--;
      if(count==0)
        v(rw);
    v(mutex);
}
}

这里面用到的信号量w,是用来防插队的,防止后来的读者抢占在写着前面,使写着得不到处理,这里面用来记录读者数量个的计数器是一定要互斥访问的,不然在读进程的并发执行过程中就会出现错误。

  • 哲学家进餐问题
    只有当哲学家拿到两个筷子的时候才可以用餐,这个问题就是涉及到多个进程(哲学家)问题,每一个哲学家即一个进程,若采取每个哲学家先取左手边筷子则很容易出现每个哲学家都拿齐了自己的左手边的筷子而导致每个人都有一个筷子并被阻塞,唔认得道第二支筷子而陷入了死锁。
    现以五个哲学家为例,解决此问题的一个方法就是让哲学家一次同时拿起两个筷子,如果不能拿到两个,就放弃,也就是说每个哲学家进程在拿两支筷子的过程是互斥的。
semaphore chopstick[5]={1,1,1,1,1};
semaphore mutex=1;
Pi(){
while(1){
    p(mutex);
      p(chopstick[i]);
      p(chopstick[(i+1)%5]);
    v(mutex);
        take the meal;
      v(chopstick[i]);
      v(chopstick[(i+1)%5]);
}
}
  • 吸烟者问题
    这个问题里面有一个提供者,提供三种材料,但每次只向盘子中放其中两种材料
    三个吸烟者,每个人都只有三种材料之中的一种且都各不相同;
    所以这是一个同步的问题
int random;
semaphore plate=1;
semaphore offer0=0;
semaphore offer1=0;
semaphore offer2=0
producer(){
while(1){
int random=random%3;
if(random==0)
v(offer0);
esle if(random==1){
v(offer1);
else if(random==2)
v(offer2);
p(plate);
}
}
smoker0(){
while(1){
p(offer0);
get the smoke;
v(plate);
}
}
smoker1(){
while(1){
p(offer1);
get the smoke;
v(plate);
}
}
smoker2(){
while(1){
p(offer2);
get the smoke;
v(plate);
}
}

对于一个信号量K 当它大于零时表示还有资源剩余,当其为负数时表示系统中等待资源的进程数目|K|
注意:若遇到类似生产者消费者问题中的同一生产者对应多个不同消费者时,要记得分情况来写,在生产进程中用信号量将多个消费进程分开即通过内部的判断 来决定执行那个消费者的V,这是这类问题的普遍解法。
在写V操作的时候要清楚了解顺序的问题,这是一个值得仔细思考的地方。
在做PV操作类的题目首先要明确,临界区是哪块,通常为共享缓冲区,对着干临界区是否要互斥,这个经常忘记,在写了同步之后就把互斥忘记了。注意点

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 204,793评论 6 478
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 87,567评论 2 381
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 151,342评论 0 338
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 54,825评论 1 277
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 63,814评论 5 368
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 48,680评论 1 281
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 38,033评论 3 399
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,687评论 0 258
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 42,175评论 1 300
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,668评论 2 321
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 37,775评论 1 332
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,419评论 4 321
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 39,020评论 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 29,978评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,206评论 1 260
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 45,092评论 2 351
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,510评论 2 343

推荐阅读更多精彩内容