进程互斥与同步

(1)

并发处理:排队等候、唤醒、执行

并发(宏观):在同一时间内,可以处理多个活动的能力,并发不一定并行。一个CPU在若干道程序实现。

并行:在同一时间内,同时发生事件。多个程序在不同CPU上同时执行。

(2)

进程间关系:竞争关系、协作关系。策略:进程同步、进程互斥、

(3)

进程同步:并发进程在某个条件下协调完成共同任务。

进程互斥:逐次使用互斥共享资源,也是一种并发进程协调完成共同任务。

(4)

在竞争资源里的死锁和饥饿:

死锁:永远等待资源。两个进程是同步的,发生资源冲突,两个进程都无法实现。

饥饿:因为优先级问题,调度的程序无限延期不能执行。异步的,永远在等待前面优先级高的进程释放资源。

(5)

临界区:并发进程与共享变量有关的程序段。

临界资源:被多线程同时访问的一份资源

访问冲突:1.一次只有一个进程可进入临界执行。2.已有进程时让其它试图进入的进程等待 。 3.进入临界的进程有限时间内退出

                  总结:互斥使用,有空让进。忙则要等,有限等待。择一而入,算法可行。

 (6)

信号量:大于0表可用资源数;小于0表被阻塞进程数。

(7)

可重复调用的PV:

                     子函数BP、BV

                      先建立S记录型的数据结构,然后建立BP和BV子函数

                       S记录型数据结构:定义value值(0或1),和等待信号量进程队列list

                      typedef struct binary_semaphore{

                      int value;

                      struct pcb*list; 

                      }

                      BP:导入记录S,判断S记录下的value值,为1则让value的值为0表示有进程进入临界,否则让进程进入等待队列沉睡

                      void BP(binary_semaphore s){

                           if(s.value==1)

                                 s.value=0;

                          else

                               sleep(s.list);

                         }

                     BV:导入记录S,判断S记录下的value值 ,若等待队列为空,让value为1表示无进程进入临界。否则,唤醒等待队列中的进程。

                        void BV(binary_semaphore s){

                           if(s.list is empty)

                                 s.value=1;

                          else

                               wakeup(s.list);

                         }

                   /五个哲学家吃面问题/:两个信号量

                   main:定义一个数组将5个哲学家依次放入数组,并附初值为1(for 循环)

                               依次放入进程:当数组不为空时,哲学家想就餐就要依次进行抢左边和右边的两把叉子,即调用两次BP子函数。

                               之后吃完再放下左边和右边的叉子,即调用两次BV子函数进行资源释放。

                   semaphore fork[5];

                  for(int i=0;i<5;i++){

                   fork[i]=1;

                   }

                  cobegin

                            process philosopher_i(){

                               while(true){

                                  think();

                                   P(fork[i]);

                                   P(fork[(i+1)%5]);

                                    eat();

                                   V(fork[i]);

                                  V (fork[(i+1)%5]);

                                      }

                     }

                   coend

                  /一个超市有n个顾客购物,只有一个收银员/ 收银员:一个信号量、n个顾客:数组大小,进程数目

                   main:定义一个数组空间为n的数组,将n个顾客依次放入。

                              依次放入进程:当数组不为空时,顾客想要结帐需要等待收银员空闲,即调用一次BP子函数。

                              之后结完帐,调用一次BV子函数,表示收银员空闲。

                 semaphore fork[n];

                  for(int i=0;i<n;i++){

                   fork[i]=1;

                   }

                  cobegin

                            process philosopher_i(){

                               while(true){

                                  think();

                                   P(fork[i]);

                                   check();

                                   V(fork[i]);

                                      }

                     }

                   coend

                              

 

posted on 2019-04-23 16:26  jslefjhw  阅读(234)  评论(0)    收藏  举报