经典进程同步问题

来源:互联网 发布:女明星淘宝店铺大全 编辑:程序博客网 时间:2024/05/18 03:06

经典进程同步问题

笔者最近正在复习操作系统相关知识,结合教材, 将最经典的生产者消费者问题以及读者写者问题的样例代码整理如下:

Tip:wait与signal操作

wait表示为信号量减一,当信号量不够减时(信号量 <= 0 时),说明当前资源不足,发出资源请求的进程阻塞直到资源可达。
signal 表示为信号量加一,表示释放了当前信号量所指代的资源。两者都是原子操作,不可打断。

生产者消费者问题

原理

生产者不停的向消息队列中生产消息,消费者则不停的从消息队列中获取消息。当消息队列满时,生产者阻塞。当消息队列空时,消费者堵塞。消息队列为互斥使用。

代码

int in = 0, out  = 0;       // in代表插入消息的位置,out代表取得消息的位置item buffer[n];     //消息队列,存储容量为nint mutex = 1;      //消息队列互斥量,由于只有一个消息队列,故为1int full = 0 , empty = n;       // full记录当前存入的消息个数,empty代表队列当前空位个数void producer(){    while(true){        wait(empty) ;       //等待empty,只有在empty为非0时,生产者才可以生产        wait(mutex);        //等待消息队列,实现对消息池的互斥使用        Item newItem = new Item();  //生产消息        buffer[in] = newItem;        in = (in + 1) % n;      //循环存取消息        signal(mutex);      //释放消息队列        signal(full);       // 为full加一    }}void consumer(){    while(true){        wait(full);     //等待消息的出现,只有当消息为空时消费者阻塞        wait(mutex);    //争取消息队列的使用权        consumeMessage(buffer[out]);    //消费消息        out = (out + 1) % n;    //循环取出消息        signal(mutex);      //释放消息队列互斥量        signal(empty);      //为empty加一,表示取出了一个消息    }}

读者写者问题

原理

写者不停的向消息池里写入消息,当写入时是不允许读取。这里就需要一个互斥量了。读者在写者空闲时会读取消息,且允许多个读者同时读取消息,因此就需要一个readCount变量记录当前读者的个数。当readCount为0时,写者可以占据消息池并进行写入

代码

int readCount = 0;      //记录读者的个数int readCountMutex = 1;     // readCount变量互斥量,当多个读者读入变量时,势必出现并发修改的问题,因此需要控制一下int msgPoolMutex = 1;       //消息池互斥量,写时不能读,读时不能写void reader(){    wait(readCountMutex);       //争取到readCount的修改权    if(readCountMutex == 0) {        wait(msgPoolMutex); //如果没有读者,说明它就是第一个读者,它需要和写者竞争消息池的使用权    }    readCount++;                //读者数量加一,并释放readCount的修改权    signal(readCountMutex);     //释放readCount的修改权    reading....    wait(readCountMutex);       // 锁定readCount的修改权    readCount--;                // 读完了,读者数减一    if(readCount == 0) {        signal(msgPoolMutex);   //作为最后一个读者,那么就无需继续保留消息池的使用权,故予以释放    }    signal(readCountMutex); //释放readCount的修改权}void writer() {    /*    * 锁定消息池,写数据,释放消息池,周而复始    */    while(true){        wait(msgPoolMutex);        writting.....        signal(msgPoolMutex);    }}
0 0