生产者-消费者问题(进程同步问题)

Posted xxrlz

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了生产者-消费者问题(进程同步问题)相关的知识,希望对你有一定的参考价值。

最近在学线程,在加上操作系统也在学线程,于是乎有了这篇文章

问题描述:

一群生产者进程在生成产品,并将这些产品提供给消费者进程去消费. 他们之间有一个公共的缓冲区用来存放产品,当产品为空时消费者不能消费,当产品为满时生产者不能生产

CPP实现

  • 利用mutex 互斥量 来对缓存区的操作进行加锁
#include<iostream>
#include<mutex>
#include<chrono>
#include<thread>
using namespace std;

int n=10;               // 缓存区大小
int in=0,out = 0;       // 生产指针,消费指针
int full = 0,empty=10;  // 空与满
int buffer[10];         // 缓存区
mutex mtx;              // 互斥量

/**
*   生产者函数
*/   
void producer(){
    do{
        while(full==n); 
        this_thread::sleep_for(chrono::seconds(1));         
        mtx.lock();     
        buffer[in] = 1; 
        in = (in+1)%n;
        cout << "生产者生产:" << in << endl; 
        empty--;
        full++;
        mtx.unlock();
    }while(true);
}
/**
*   消费者函数
*/
void consumer(){
    do{
        while(empty==10);
        mtx.lock();
        buffer[out] = 0;
        out=(out+1)%n;
        cout <<"消费者消费:" << out << endl; 
        empty++;
        full--;
        mtx.unlock();
        this_thread::sleep_for(chrono::seconds(2));
    }while(true);
}
int main(){
    
    thread t1{producer};
    thread t2{consumer};
    
    t1.join();
    t2.join();
    return 0;
} 

Java实现

用Storage对象模拟缓存区,关键代码如下


/**
*   存储类
*/
public class Storage {
    private Product[] products = new Product[10];
    private int top = 0;

    public synchronized void push(Product product){
        while(top == products.length){
            try{
                System.out.println("producer wait");
                wait();                                 //缓冲区满,无法生产,则阻塞
            }catch (InterruptedException e){
                e.printStackTrace();
            }
        }

        products[top++] = product;
        System.out.println(Thread.currentThread().getName()+" 生产了 "+product);
        System.out.println("producer notifyAll");
        notifyAll();                                    //生产出新的产品,唤醒消费者进程
    }

    public synchronized Product pop(){
        while (top==0){
            try{
                System.out.println("consumer wait");;
                wait();                                 //缓冲区空,无法消费,阻塞
            }catch (InterruptedException e){
                e.printStackTrace();
            }
        }
        --top;
        Product p = new Product(products[top].getId(),products[top].getName());
        products[top] = null;
        System.out.println(Thread.currentThread().getName()+ " 消费了 "+p);
        System.out.println("consumer notifyAll");
        notifyAll();                                    //消费了产品,唤醒生产者
        return p;
    }
}

public class Producer implements Runnable{
    private Storage storage;

    public Producer(Storage storage){
        this.storage = storage;
    }

    @Override
    public void run() {
        int i=0;
        Random r = new Random();
        while(i<10){
            i++;
            Product product = new Product(i,"电话"+r.nextInt(100));
            storage.push(product);
        }
    }
}

public class Consumer implements Runnable{
    private Storage storage;

    public Consumer(Storage storage){
        this.storage = storage;
    }

    @Override
    public void run() {
        int i=0;
        while (i<10){
            i++;
            storage.pop();
            try {
                Thread.sleep(1000);
            }catch (InterruptedException e){
                e.printStackTrace();
            }
        }
    }
}

以上是关于生产者-消费者问题(进程同步问题)的主要内容,如果未能解决你的问题,请参考以下文章

经典进程的同步问题生产者-消费者问题

(王道408考研操作系统)第二章进程管理-第三节6:经典同步问题之生产者与消费者问题

进程同步——生产者消费者问题

生产者-消费者问题(进程同步问题)

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

经典进程同步问题