生成者-消费者问题

     对于生产者-消费者问题,有时候也称为有界缓冲区(bounded-buffer)问题。两个进程共享一个公共的固定大小的缓冲区。其中一个是生产者,将消息放入缓冲区;另一个是消费者,从缓冲区取出消息。(也可以把这个问题一般化为m个生产者和n个消费者的问题,但是我们只讨论一个生产者和一个消费者的问题,这样可以简化解决方案)。

  对于这个问题解决的逻辑是这样的:这个问题在于当缓冲区已满,而此时生成者还想向其中放入一个新的数据项的情况。其解决的办法。是让生产者睡眠,待消费者从缓冲区取出一个或者多个数据项时再唤醒它。同样地,当消费者试图从缓冲区取数据而发现缓冲区为空,消费者就睡眠,直到生产者向其中放入一些数据时再将其唤醒。

  生产者-消费者,c语言解决办法:

#define N 100

int count = 0;

void producer(void)

{

  int item;

  while(TRUE){

    item = produce_item();

    if(count == N) sleep();

    insert_item(item);

    count = count + 1;

    if(count == 1) wakeup(consumer);

  }

}

 

void consumer(void)

{

  int item;

   while(TRUE){

    if(count==0)sleep();

    item = remove_item();

    count = count -1;

    if(count = N-1) wakeup(producer);

    consume_item(item);

  }

}

 

使用信号量解决的生产者-消费者问题:

#define N 100

typedef int semaphore;

semaphore mutex = 1;

semaphore empty =1;

semaphore full = 0;

 

void producer(void)

{

  int item;

  while(TRUE){

    item = produce_item();

    down(&empty);

    down(&mutex);

    insert_item(item);

    up(&mutex);

    up(&full);

  }

}

 

void consumer(void)

{

  int item;

  while(TRUE){

    down(&full);

    down(&mutex);

    item = remove_item();

    up(&mutex);

    up(&empty);

    consume_item(item);

  }

}

利用线程解决生产者消费者问题(要研究线程、互测量、条件变量),下面这是在只有一个缓冲区的生产者-消费者问题:

#include <stdio.h>

#include <pthread.h>

#define MAX 1000000000

pthread_mutex_t the_mutex;

pthread_cond_t condc,condp;

int buffer = 0;

void *producer(void *ptr)

{

  int i;

  for(int i=1;i<= MAX ;i++){

    pthread_mutex_lock(&the_mutex);

    while(buffer != 0)pthread_cond_wait(&condp,&the_mutex);

    buffer = i;

    pthread_cond_signal(&condc);

    pthread_mutex_unlock(&the_mutex);

  }

  pthread_exit(0);

}

 

void *consumer(void *ptr)

{

  int i;

  for(i = 1;i <= MAX,i++){

    pthread_mutex_lock(&the_mutex);

    while(buffer ==0) pthread_cond_wait(&condc,&the_mutex);

    buffer = 0;

    pthread_cond_signal(&condp);

    pthread_mutex_unlock(&the_mutex);

  }

  pthread_exit(0);

}

 

int main(int argc,char **argv)

{

  pthread_t pro,con;

  pthread_mutex_init(&the_mutex,0);

  pthread_cond_init(&condc,0);

  pthread_cond_init(&condp,0);

  pthread_create(&con,0,consumer,0);

  pthread_create(&pro,0,producer,0);

  pthread_join(pro,0);

  pthread_join(con,0);

  pthread_cond_destory(&condc);

  pthread_cond_destory(&condp);

  pthread_mutex_destory(&the_mutex);

}

 对于,java语言由于其支持管程(管程是编程语言的概念,c/c++/pascal语言均不支持),所以处理上面来说比较方便;

下面是使用java语言实现的生产者-消费者问题的解法:

public class ProducerConsumer{

  static final int N = 100;

  static producer p = new producer();

  static consumer c = new consumer();

  static our_monitor mon = new our_monitor();

  

  public static void main(String args[]){

    p.start();

    p.start();

  }

 

  static class producer extends Thread{

    public void run(){

      int item;

      while(true){

        item = produce_item();

        mon.insert(item);

      }

    }

    private int produce_item(){.....}//实际生产

  }

    

  static class consumer extends Thread{

    public void run(){

      int item;

      while(true){

        item = mon.remove();

        consume_item(item);

      }

    }

    private void consume_item(int item){...}//实际消费

  }

  

  static class our_monitor{

    private int buffer[] = new int[N];

    private int count = 0,lo = 0,hi = 0;

  

    public synchronized void insert(int val){

      if(count == N) go_to_sleep();

      buffer[hi] = val;

      hi = (hi +1) % N;

      count = count +1;

      if(count ==1)notify();

    }

 

    public synchronized int remove(){

      int val;

      if(count == 0)go_to_sleep();

      val = buffer[lo];

      lo = (lo +1)%N;

      count = count -1;

      if(count == N-1) notify();

      return val;

    }

    private void go_to_sleep(){try{wait();}catch(){InterruptedException exc};}

  }

}

用N条消息实现的生产者-消费者问题

#define N 100

 

void producer(void)

{

  int item;

  message m;,

  while(TRUE){

    item = produce_item();

    receive(consumer,&m);

    build_message(&m,item);

    send(consumer,&m);

  }

}

 

void consumer(void)

{

  int item,i;

  message m;

  for(i = 0;i<N; i++)send(producer,&m);

  while(TRUE){

    receive(producer,&m);

    item = extract_item(&m);

    send(producer,&m);

    consume_item(item);

  }

}

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

你可能感兴趣的:(消费者)