最近在學線程,在加上操作系統也在學線程,於是乎有了這篇文章
問題描述:
一群生產者進程在生成產品,並將這些產品提供給消費者進程去消費. 他們之間有一個公共的緩沖區用來存放產品,當產品為空時消費者不能消費,當產品為滿時生產者不能生產
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();
}
}
}
}