生产者-消费者问题
来源:互联网 发布:数控螺纹g76编程格式 编辑:程序博客网 时间:2024/05/16 07:21
生产者-消费者是很有意思的一种算法。它的存在主要是两个目的,第一就是满足生产者对资源的不断创造;第二就是满足消费者对资源的不断索取。当然,因为空间是有限的,所以资源既不能无限存储,也不能无限索取。
生产者-消费者问题是一个经典的进程同步问题,该问题最早由Dijkstra提出,用以演示他提出的信号量机制。在同一个进程地址空间内执行的两个线程。生产者线程生产物品,然后将物品放置在一个空缓冲区中供消费者线程消费。消费者线程从缓冲区中获得物品,然后释放缓冲区。当生产者线程生产物品时,如果没有空缓冲区可用,那么生产者线程必须等待消费者线程释放出一个空缓冲区。当消费者线程消费物品时,如果没有满的缓冲区,那么消费者线程将被阻塞,直到新的物品被生产出来。
以下linux程序展示的是一个生产者和一个消费者共享一个NBUFF大小的缓冲区进行同步的演示
- #include<stdio.h>
- #include<string.h>
- #include<pthread.h>
- #include<unistd.h>
- #include<semaphore.h>
- #include<fcntl.h>
- #include<sys/stat.h>
- #define NBUFF 10 // 缓冲区大小
- #define SEM_MUTEX "mutex"
- #define SEM_NEMPTY "nempty"
- #define SEM_NSTORED "nstored"
- static int nitems = NBUFF;
- struct _shared
- {
- int buff[ NBUFF ]; // 缓冲区大小
- sem_t* mutex; // 访问缓冲区的互斥锁
- sem_t* nempty; // 当前空闲的缓冲区个数
- sem_t* nstored; // 当前缓冲区可用个数
- } shared; // 线程共享量
- void* producer( void* );
- void* consumer( void* );
- int main( int argc, char** argv )
- {
- pthread_t tid_producer, tid_consumer;
- memset( shared.buff, 0, sizeof( shared.buff ) );
- shared.mutex = sem_open( SEM_MUTEX, O_CREAT | O_EXCL, 0644, 1 );
- shared.nempty = sem_open( SEM_NEMPTY, O_CREAT | O_EXCL, 0644, NBUFF );
- shared.nstored = sem_open( SEM_NSTORED, O_CREAT | O_EXCL, 0644, 0 );
- pthread_setconcurrency( 2 );
- // create producer and consumer
- pthread_create( &tid_producer, NULL, producer, NULL );
- pthread_create( &tid_consumer, NULL, consumer, NULL );
- // wait for two threads
- pthread_join( tid_producer, NULL );
- pthread_join( tid_consumer, NULL );
- // remove semaphores
- sem_unlink( SEM_MUTEX );
- sem_unlink( SEM_NEMPTY );
- sem_unlink( SEM_NSTORED );
- return 0;
- }
- void* producer( void* arg )
- {
- int i ;
- for ( i = 0; i < nitems; i++ )
- {
- sem_wait( shared.nempty ); // P( nempty )
- sem_wait( shared.mutex ); // P( mutex )
- shared.buff[ i % NBUFF ] = i;
- printf( "producer: %d\n", shared.buff[ i % NBUFF ] );
- sem_post( shared.mutex ); // V( mutex )
- sem_post( shared.nstored ); // V( nstored )
- sleep( 1 ); // 暂停,唤醒consumer
- }
- return ( void* )0;
- }
- void* consumer( void* arg )
- {
- int i;
- for ( i = 0; i < nitems; i++ )
- {
- sem_wait( shared.nstored ); // P( nstored )
- sem_wait( shared.mutex ); // P( mutex )
- printf( "consumer: buff[%d] = %d\n", i, shared.buff[ i % NBUFF ] );
- sem_post( shared.mutex ); // V( mutex )
- sem_post( shared.nempty ); // V( empty )
- sleep( 2 ); // 暂停,唤醒producer
- }
- return ( void* )0;
- }
#include<stdio.h>#include<string.h>#include<pthread.h>#include<unistd.h>#include<semaphore.h>#include<fcntl.h>#include<sys/stat.h>#define NBUFF 10 // 缓冲区大小#define SEM_MUTEX "mutex" #define SEM_NEMPTY "nempty" #define SEM_NSTORED "nstored" static int nitems = NBUFF;struct _shared{ int buff[ NBUFF ]; // 缓冲区大小 sem_t* mutex; // 访问缓冲区的互斥锁 sem_t* nempty; // 当前空闲的缓冲区个数 sem_t* nstored; // 当前缓冲区可用个数} shared; // 线程共享量void* producer( void* );void* consumer( void* );int main( int argc, char** argv ){ pthread_t tid_producer, tid_consumer; memset( shared.buff, 0, sizeof( shared.buff ) ); shared.mutex = sem_open( SEM_MUTEX, O_CREAT | O_EXCL, 0644, 1 ); shared.nempty = sem_open( SEM_NEMPTY, O_CREAT | O_EXCL, 0644, NBUFF ); shared.nstored = sem_open( SEM_NSTORED, O_CREAT | O_EXCL, 0644, 0 ); pthread_setconcurrency( 2 ); // create producer and consumer pthread_create( &tid_producer, NULL, producer, NULL ); pthread_create( &tid_consumer, NULL, consumer, NULL ); // wait for two threads pthread_join( tid_producer, NULL ); pthread_join( tid_consumer, NULL ); // remove semaphores sem_unlink( SEM_MUTEX ); sem_unlink( SEM_NEMPTY ); sem_unlink( SEM_NSTORED ); return 0;}void* producer( void* arg ){ int i ; for ( i = 0; i < nitems; i++ ) { sem_wait( shared.nempty ); // P( nempty ) sem_wait( shared.mutex ); // P( mutex ) shared.buff[ i % NBUFF ] = i; printf( "producer: %d\n", shared.buff[ i % NBUFF ] ); sem_post( shared.mutex ); // V( mutex ) sem_post( shared.nstored ); // V( nstored ) sleep( 1 ); // 暂停,唤醒consumer } return ( void* )0;}void* consumer( void* arg ){ int i; for ( i = 0; i < nitems; i++ ) { sem_wait( shared.nstored ); // P( nstored ) sem_wait( shared.mutex ); // P( mutex ) printf( "consumer: buff[%d] = %d\n", i, shared.buff[ i % NBUFF ] ); sem_post( shared.mutex ); // V( mutex ) sem_post( shared.nempty ); // V( empty ) sleep( 2 ); // 暂停,唤醒producer } return ( void* )0;}
// 编译
- kennie@cbib:~/pthreadDIR$ g++ -lpthread -o producer_consumer.out producer_consumer.cpp
kennie@cbib:~/pthreadDIR$ g++ -lpthread -o producer_consumer.out producer_consumer.cpp
// 运行结果
- producer: 0
- consumer: buff[0] = 0
- producer: 1
- consumer: buff[1] = 1
- producer: 2
- producer: 3
- consumer: buff[2] = 2
- producer: 4
- producer: 5
- consumer: buff[3] = 3
- producer: 6
- producer: 7
- consumer: buff[4] = 4
- producer: 8
- producer: 9
- consumer: buff[5] = 5
- consumer: buff[6] = 6
- consumer: buff[7] = 7
- consumer: buff[8] = 8
- consumer: buff[9] = 9
- 生产者-消费者问题
- 生产者-消费者问题
- 生产者-消费者问题
- 操作系统:生产者-消费者问题
- 生产者与消费者问题
- 生产者-消费者问题
- 关于生产者-消费者问题
- java生产者 消费者问题
- 消费者和生产者问题
- 生产者消费者问题
- 生产者消费者问题--多线程
- 生产者-消费者同步问题
- 生产者消费者问题
- 生产者与消费者问题
- 生产者 消费者问题!
- 生产者与消费者问题
- 生产者消费者问题
- 关于生产者-消费者问题
- Intent跳转到系统应用中的拨号界面、联系人界面、短信界面及其他
- 映射网络驱动器MFC
- 莫言教学常启迪学生多动脑 主张把自己当罪人写-莫言-诺贝尔文学奖-兰传斌
- rails rspec测试
- myeclipse安装SVN
- 生产者-消费者问题
- 原码、反码和补码理解
- Ubuntu 开启 SSH服务
- 和菜鸟一起学数据结构之简单静态链表实现
- 成都国安局称1名男子泄漏王立军案侦办信息被拘-成都-王立军-侦办
- mobile agent 学习
- 虚拟化、云计算、开放源代码及其他
- 第七周任务 3-5
- hdu1582AC again-bfs