【操作系统总结】经典的进程同步问题-生产者消费者问题

生产者消费者问题

问题描述是:有一群生产者进程在生产产品,此产品提供给消费者去消费。为使生产者和消费者进程能并发执行,在它们之间设置一个具有n个缓冲池,生产者进程可将它所生产的产品放入一个缓冲池中,消费者进程可从一个缓冲区取得一个产品消费。

利用记录型信号量

semaphore mutex=1,empty=n,full=0;
item buffer[n];   //缓冲区
int in=out=0;   //输入、输出指针
void producer()  

{    

     while(1)
    {
         …
         生产一个产品nextp;
        …
        wait(empty);  //首先对empty--判断他是否小于0,小于0就自我阻塞
        wait(mutex);  //拿到锁,否则就自我阻塞   

        buffer[in]= nextp; //往Buffer [in]放产品
        in = (in+1) % n;
        signal(mutex);  //释放锁
        signal(full);   //对full++判断是否<=0,如果是就唤醒进程
   }
}

void consumer()
{
     while(1)
    {   ……
        wait(full); //首先对full--判断他是否小于0,小于0就自我阻塞
        wait(mutex); //拿到锁,否则就自我阻塞
        nextc = buffer[out]; //从Buffer [out]取产品
        out = (out +1) mod n;
        signal(mutex); //释放锁
        signal(empty); //对empty++判断是否<=0,如果是就唤醒进程
                                   消费nextc产品;
      }
}

main()
{
    cobegin{
    producer();
    consumer();
}

利用AND型信号量

semaphore mutex=1,empty=n,full=0;
item buffer[n];   //缓冲区
int in=out=0;   //输入、输出指针
void producer()  

{    

     while(1)

    {    

    …
      生产一个产品nextp;
    …
    swait(empty, mutex);//当empty和mutex都大于0,否则自我阻塞
    buffer[in]= nextp; //往Buffer [in]放产品
    in = (in+1) mod n;
    ssignal(mutex, full);//把锁设回来,然后full+1
     }

}

void consumer()  

{    

     while(1)

    {        

        ……

        swait(full, mutex);当full和mutex都大于0,否则自我阻塞
        nextc = buffer[out];  //从Buffer [out]取产品
        out = (out +1) mod n;
        signal(mutex, empty);把锁设回来,然后empty+1
            消费nextc产品;
         }
}

利用管程

//建立一个管程结构
Monitor produceconsumer {
    item buffer[N];//缓冲区
    int in, out;
    condition notfull, notempty;
    int count;
    public:
    void put(item x) {
        if(cout >= N) cwait(notfull);//如果里面的量已经等于N,就让这个进程阻塞
        buffer[in]  = x;//否则就放东西
        in = (in + 1) % N;
        count++;
        csignal(notempty);//如果不为空就唤醒消费者进程
    }

    void get(item x) {
        if(count <= 0) cwait(notempty);//如果是空,就让这个进程阻塞
        x = buffer[out];
        out = (out + 1) % N;
        count--;
        csignal(notfull);//不满的话就唤醒生产者进程
    }

    {
        in = 0;
        out = 0;
        count = 0;
    }
}PC;

void producer() {
    item x;
    while(1) {
        在缓冲区放东西
        PC.put(x);
    }
}

voif consumer() {
    item x;
    while(1) {
        PC.get(x);
        从缓冲区取东西
    }
}

void main() {
    cobegin;
    proceducer();
    consumer();
    conend;
}
时间: 2024-08-02 03:08:18

【操作系统总结】经典的进程同步问题-生产者消费者问题的相关文章

【操作系统】经典的同步问题(生产者消费者问题, 哲学家进餐问题, 读写问题)

用专业术语来说, 进程是程序的一次动态执行.说简单点, 就是进程是系统中的某个任务.操作系统中有多个任务需要执行, 那么怎样执行才能使它们同步呢? 即如何让任务并发执行互不影响呢? 这就引出了进程同步中的经典问题: 生产者消费者问题, 哲学家进餐问题, 读写问题 生产者-消费者问题 有一群生产者进程在生产产品, 并将这些产品提供给消费者进程取消费. 为使生产者进程与消费者进程能并发进行, 在两者间设置了一个具有n个缓冲区的缓冲池, 生产者进程将其所生产的产品翻入缓冲区中, 消费者进程可从一个缓冲

生产者消费者之信号量的使用

实验报告 一.实验目的 1.熟悉临界资源.信号量及PV操作的定义与物理意义 2.了解进程通信的方法 3.掌握进程互斥与同步的相关知识 4.掌握用信号量机制解决进程之间的同步与互斥问题 5.实现生产者-消费者问题,深刻理解进程同步问题 二.实验环境 Linux系统 三.实验内容 在Linux操作系统下用C或C++实现经典同步问题:生产者-消费者问题,具体要求如下: 1. 一个大小为10的缓冲区,初始状态为空. 2. 2个生产者,随机等待一段时间,往缓冲区中添加数据,若缓冲区已满,等待消费者取走数据

Java多线程实现生产者消费者延伸问题

在操作系统中有一类问题被称为生产者消费者问题:意为,有数个生产者生产产品,有数个消费者消费产品,他们共享一定数量的缓存. 这里用java多线程编程,实现生产者消费者问题的一种延伸,橘子苹果问题. 题目如下: 有苹果橘子生产者各20个,有苹果橘子消费者各20个,他们公用20个缓存区.要求能随时查看缓存区内容,随时查看生产消费内容情况,随时暂停生产开始生产. 我们的实现思路: 1.首先创建一个缓存区类,其中包含静态的,长度大小为20的数组,用来存放和取出生产的产品:一个静态的日志变量List,用来记

经典进程同步问题一:生产者-消费者问题(The producer-consumer problem)

(注:参考教材:计算机操作系统第四版 西安电子科技大学出版社) 问题描述:一群生产者进程在生产产品,并将这些产品提供给消费者去消费.为了使生产者进程与消费者进程能够并发进行,在两者之间设置一个具有n个缓冲区的缓冲池,生产者进程将产品放入一个缓冲区中:消费者可以从一个缓冲区取走产品去消费.尽管所有的生产者进程和消费者进程是以异方式运行,但它们必须保持同步:当一个缓冲区为空时不允许消费者去取走产品,当一个缓冲区满时也不允许生产者去存入产品. 解决方案:我们这里利用一个一个数组buffer来表示这个n

java基础知识回顾之java Thread类学习(八)--java多线程通信等待唤醒机制经典应用(生产者消费者)

 *java多线程--等待唤醒机制:经典的体现"生产者和消费者模型 *对于此模型,应该明确以下几点: *1.生产者仅仅在仓库未满的时候生产,仓库满了则停止生产. *2.消费者仅仅在有产品的时候才能消费,仓空则等待. *3.当消费者发现仓储没有产品可消费的时候,会唤醒等待生产者生产. *4.生产者在生产出可以消费的产品的时候,应该通知等待的消费者去消费. 下面先介绍个简单的生产者消费者例子:本例只适用于两个线程,一个线程生产,一个线程负责消费. 生产一个资源,就得消费一个资源. 代码如下: pub

Ruby:线程实现经典的生产者消费者问题

运行结果: ProAndCon 0 produced 1 produced consumed 0 2 produced 3 produced consumed 1 consumed 2 consumed 3 4 produced consumed 4 5 produced consumed 5 转载自:http://www.oschina.net/code/snippet_1045481_33311 Ruby:线程实现经典的生产者消费者问题,布布扣,bubuko.com

JS实现经典生产者消费者模型

由于node使用单线程的方式实现,所以,在此使用定时器timer代替线程thread来实现生产者消费者模型. 代码如下: var sigintCount = 0; var productArray = []; var productArrayLen = 0; var productLock = false; var PRODUCT_ARRAY_THRESHOLD = 10; var producerTimer = setInterval(function () { if (!productLoc

Python之路(第三十八篇) 并发编程:进程同步锁/互斥锁、信号量、事件、队列、生产者消费者模型

一.进程锁(同步锁/互斥锁) 进程之间数据不共享,但是共享同一套文件系统,所以访问同一个文件,或同一个打印终端,是没有问题的, 而共享带来的是竞争,竞争带来的结果就是错乱,如何控制,就是加锁处理. 例子 #并发运行,效率高,但竞争同一打印终端,带来了打印错乱 from multiprocessing import Process import os,time def work(): print('%s is running' %os.getpid()) time.sleep(2) print('

生产者消费者问题、Java实现

来,今天尝试把这个问题搞定.还是这种节奏,看一个问题要先从历史看.全局看,这样我们才能真正掌握其全貌,最终各个击破,了然于胸! 我们先来温习下如下概念: 1. 基础概念 基本的 程序 - Program 程序是静态的源代码或目标程序,是一个没有生命的实体. 进程 - Process 当CPU赋予程序生命时也即操作系统执行它时,程序成为了一个活动的实体(但不是可执行的实体),称为进程 - 进行中的程序. 进程是程序的一个实例: 是计算机分配资源的基本单位: 是线程的容器: 线程 - Thread