操作系统: 生产者-消费者问题

操作系统: 生产者-消费者问题

1、单生产者和单消费者

     缓存绑定问题,两个进程:生产者和消费者,一个固定大小的缓存。

     生产者的工作就是制造一段数据,放进缓存,如此反复;

     消费者则一次消费一段数据(将其从缓存中移除),

     问题的核心: 就是要保证不让生产者在缓存还是满的时候仍要向缓存写数据,

                            不让消费者试图从空的缓存中取出数据。

该问题需要注意的几点:

  • 在缓冲区为空时,消费者不能再进行消费
  • 在缓冲区为满时,生产者不能再进行生产
  • 在一个线程进行生产或消费时,其余线程不能再进行生产或消费等操作,即保持线程间的同步
  • 注意条件变量与互斥锁的顺序

伪代码实现

假设缓冲区大小为10,生产者、消费者线程若干。

 生产者和消费者相互等效,只要缓冲池未满,生产者便可将消息送入缓冲池;

 只要缓冲池未空,消费者便可从缓冲池中取走一个消息。

 items       代表缓冲区已经使用的资源数,spaces代表缓冲区可用资源数
 mutex      代表互斥锁
 buf[10]    代表缓冲区,其内容类型为item
 in、out   代表第一个资源和最后一个资源

var items = 0, space = 10, mutex = 1;
var in = 0, out = 0;
item buf[10] = { NULL };

producer {
    while( true ) {
        wait( space );  // 等待缓冲区有空闲位置, 在使用PV操作时,条件变量需要在互斥锁之前
        wait( mutex );  // 保证在product时不会有其他线程访问缓冲区

        // product
        buf.push( item, in );  // 将新资源放到buf[in]位置 
        in = ( in + 1 ) % 10;
        
        signal( mutex );  // 唤醒的顺序可以不同
        signal( items );  // 通知consumer缓冲区有资源可以取走
    }
}

consumer {
    while( true ) {
        wait( items );  // 等待缓冲区有资源可以使用
        wait( mutex );  // 保证在consume时不会有其他线程访问缓冲区

        // consume
        buf.pop( out );  // 将buf[out]位置的的资源取走
        out = ( out + 1 ) % 10;

        signal( mutex );  // 唤醒的顺序可以不同
        signal( space );  // 通知缓冲区有空闲位置
    }
}
发布了736 篇原创文章 · 获赞 123 · 访问量 8万+

猜你喜欢

转载自blog.csdn.net/S_999999/article/details/103648889