操作系统学习笔记——生产者与消费者,读者和写者

i.                   生产者生产一条数据

1.      首先查看缓冲区能否放入数据,有没有空的位置,如果有往下执行,否则说明缓冲区全

满了,消费者可能干什么去了没有来取数据,所以生产者阻塞等待资源,当一定的时候被唤醒(有空的了)。在此处,生产者如果发现缓冲区已经满了,生产者阻塞在此处。

2.      之后查看临界区是否可用(有没有进程在临界区),否则必须等待使用权,当使用临界资源的进程退出唤醒之。假设3个生产者都已经申请到资源,但是到此处时,只能有一个生产者可以进入,所以又要被阻塞一次。

3.      存入一条数据

4.      退出临界区,归还使用权

5.      数据单元+1,唤醒消费者。

 

ii.                 消费者消费一条数据

1.      首先查看有数据单元,如果有执行,否则消费者阻塞等待资源,直到被生产者唤醒(信号?)

2.      查看临界区是否可用,如果可用执行,否则阻塞等待使用权。

3.      从缓冲区取一条数据。

4.      归还临界区使用权

5.      空单元+1,唤醒一个生产者(数据单元-1,生产者可以生产了)

6.      消费数据

 

const int buffersize = 10;           //缓冲区大小

semaphore s = 1;                  //互斥信号量,初始化为1

semaphore n = 0;                  //资源信号量,数据单元,初始化为0

semaphore e = buffersize      //资源信号量,空存储单元

 

void producer()

{

       while(true)

       {

              produce();          //生产一条数据

              wait(e);          //i.1,查看缓冲层是否可用

              wait(s);          //i.2,查看临界区是否可用

              dosomething()       //i.3,存入一条数据

              signal(s);         //i.4,退出缓冲区,归还使用权。

              signal(n);        //i.5,数据单位+1,唤醒消费者

       }

}

 

void consumer()

{

       while(true)

       {

              wait(n);          //ii.1查看缓冲区是否可用

              wait(s);          //ii.2查看临界区是否可用

              dosomething();       //ii.3取一条数据

              signal(s);       //ii.4归还临界区使用权

              signal(e);       //ii.5空单元+1,唤醒生产者

              consume();       //消费数据

       }

}

 

 

七  读者写者问题

1.    问题描述及满足的条件

l  该问题为多个进程访问一个共享数据区建立的一个通用模型,其中若干读进程只能读数据,若干写进程只能写数据。

l  允许多个读者进程可以同时读数据。

l  不允许多个写者同时写数据,只能互斥写数据。

l  若有写者进程正在写数据,则不允许读者进程读数据。

2.    如何控制读者和写者问题

l  如果采用生产者/消费者问题解决方法,严格互斥任何读者和写者进程,可以保证数据更新操作的正确性。

l  但是对于若干读进程,严格互斥,将影响效率,应该让读者同时读数据。

l  如果一个写者进程正在修改数据,别的写者及任何读者都不难访问该数据。

3.    读者优先

l  当一个读者正在读数据,允许其他读者进入。

l  现在假设一个写者到来,由于写操作是排他的,需要阻塞等待,如果一直都有新的读者陆续到来,写者的写操作将被严重推迟。

这种方法称为“读者优先”,一旦读者正在读数据,允许多个读者同时进入读数据,只

有当全部读者退出,才允许写者进入写数据,对写者不公平.

int readcount = 0;   //读者个数

semaphore wsem = 1;                  //互斥信号量,初始化为1,互斥读者和写者

semaphore x = 1;                  //互斥修改readcount变量

void read()

{

       while(true)

       {

              ///x:读者互斥修改readcount这个变量

              wait(x);

              if(++readcount == 1)

                     wait(wsem);

              signal(x);

              ///

              readData();                   //读数据

 

              wait(x);

              if(--readcount == 0)

                     signal(wsem);

              signal(x);       

       }

}

 

void write()

{

       while(true)

       {

              wait(wsem);

              writeData();

              signal(s);

       }

}

 

4.    写者优先

l  为了防止“读者优先”可能导致写者饥饿,可以考虑写者优先。

l  即,当共享数据区被读者占用,后续紧邻到达的读者可以继续进入,若这时有一个写者到来且阻塞等待,则写者后面到来的若干读者全部阻塞。

l  这种方案解决写者饥饿问题,但降低了并发程度使系统性能较差。

 

int readcount = 0;                 //读者个数

int writecount = 0;                //写者个数

semaphore wsem = 1;                  //写者信号量,互斥写者

semaphore rsem = 1;                    //读者信号量,互斥读者

semaphore x = 1;                  //互斥修改readcount变量

semaphore y = 1;                  //互斥修改writecount变量

semaphore z = 1;                  //

 

void read()

{

       while(true)

       {

              wait(z);                 //不让读者排成长队

              wait(rsem);

              wait(x);

              if(++readcount == 1)

                     wait(wsem);

              signal(x);

              signal(rsem);

              signal(z);

              ///

              readData();                   //读数据

             

              wait(x);

              if(--readcount == 0)

                     signal(wsem);

              signal(x);       

       }

}

 

void write()

{

       while(true)

       {

              wait(y);                        //互斥

              if(++writecount == 1)

                     wait(rsem);                   //阻塞读者

              signal(y);

             

              wait(wsem);                         //写者写数据

              writeData();

              signal(wsem);

             

              wait(y);

              if(--writecount == 0)

                     signal(rsem);

              signal(y);

              signal(s);

       }

}

 

你可能感兴趣的:(操作系统学习笔记——生产者与消费者,读者和写者)