《unix网络编程》生产者消费者问题
2013-08-07 20:35
127 查看
首先是多个生产者单个消费者问题:
多个生产者定量的物品,当生产完所有物品后,后面的生产进程就应该直接return ;
一个消费者就只是从头都尾看顺序的取物品
下来是多生产者多消费者:
需要注意的就是必须有80行:sem_post(&shared.nstored);
当生产者生产完后,让每个生产者线程给nstored加1以给各个消费者线程接阻塞。不然消费者进程将永远阻塞在sem_wait(&shared.nstored)上
/* include main */ #include <semaphore.h> #include<unistd.h> #include<stdlib.h> #include<stdio.h> #include<pthread.h> #define NBUFF 10 #define MAXNTHREADS 100 int nitems, nproducers; /* read-only by producer and consumer */ struct { /* data shared by producers and consumer */ int buff[NBUFF]; int nput; int nputval; sem_t mutex, nempty, nstored; /* semaphores, not pointers */ } shared; void *produce(void *), *consume(void *); int main(int argc, char **argv) { int i, count[MAXNTHREADS]; pthread_t tid_produce[MAXNTHREADS], tid_consume; if (argc != 3) printf("usage: prodcons3 <#items> <#producers>"); nitems = atoi(argv[1]); //nproducers = min(atoi(argv[2]), MAXNTHREADS); nproducers = atoi(argv[2]); /* 4initialize three semaphores */ sem_init(&shared.mutex, 0, 1); sem_init(&shared.nempty, 0, NBUFF); sem_init(&shared.nstored, 0, 0); /* 4create all producers and one consumer */ pthread_setconcurrency(nproducers + 1); pthread_create(&tid_consume, NULL, consume, NULL); for (i = 0; i < nproducers; i++) { count[i] = 0; pthread_create(&tid_produce[i], NULL, produce, &count[i]); } /* 4wait for all producers and the consumer */ for (i = 0; i < nproducers; i++) { pthread_join(tid_produce[i], NULL); printf("count[%d] = %d\n", i, count[i]); } pthread_join(tid_consume, NULL); sem_destroy(&shared.mutex); sem_destroy(&shared.nempty); sem_destroy(&shared.nstored); exit(0); } /* end main */ /* include produce */ void * produce(void *arg) { for ( ; ; ) { sem_wait(&shared.nempty); /* wait for at least 1 empty slot */ sem_wait(&shared.mutex); if (shared.nput >= nitems) { sem_post(&shared.nempty);//这句必需,比如说10个卡槽,14个线程每个写入一个卡槽,如果不加这句,其余的4个线程将永远卡在sem_wait(&shared.nempty);这句上 sem_post(&shared.mutex); return(NULL); /* all done */ } shared.buff[shared.nput % NBUFF] = shared.nputval; printf("put: buff[%d]=%d\n",shared.nput % NBUFF,shared.nputval); shared.nput++; shared.nputval++; sem_post(&shared.mutex); sem_post(&shared.nstored); /* 1 more stored item */ *((int *) arg) += 1; } } /* end produce */ /* include consume */ void * consume(void *arg) { int i; for (i = 0; i < nitems; i++) { sem_wait(&shared.nstored); /* wait for at least 1 stored item */ sem_wait(&shared.mutex); if (shared.buff[i % NBUFF] != i) printf("error: buff[%d] = %d\n", i, shared.buff[i % NBUFF]); printf("get: buff[%d]=%d\n",i % NBUFF,i); // else printf("buff[%d] ", i); sem_post(&shared.mutex); sem_post(&shared.nempty); /* 1 more empty slot */ } return(NULL); } /* end consume */
多个生产者定量的物品,当生产完所有物品后,后面的生产进程就应该直接return ;
一个消费者就只是从头都尾看顺序的取物品
下来是多生产者多消费者:
/* include globals */ #include <semaphore.h> #include<unistd.h> #include<stdlib.h> #include<stdio.h> #include<pthread.h> #define NBUFF 10 #define MAXNTHREADs 100 int nitems, nproducers, nconsumers; /* read-only */ struct { /* data shared by producers and consumers */ int buff[NBUFF]; int nput; /* item number: 0, 1, 2, ... */ int nputval; /* value to store in buff[] */ int nget; /* item number: 0, 1, 2, ... */ int ngetval; /* value fetched from buff[] */ sem_t mutex, nempty, nstored; /* semaphores, not pointers */ } shared; void *produce(void *), *consume(void *); /* end globals */ /* include main */ int main(int argc, char **argv) { int i, prodcount[MAXNTHREADs], conscount[MAXNTHREADs]; pthread_t tid_produce[MAXNTHREADs], tid_consume[MAXNTHREADs]; if (argc != 4) printf("usage: prodcons4 <#items> <#producers> <#consumers>"); nitems = atoi(argv[1]); nproducers = atoi(argv[2]); nconsumers = atoi(argv[3]); /* 4initialize three semaphores */ sem_init(&shared.mutex, 0, 1); sem_init(&shared.nempty, 0, NBUFF); sem_init(&shared.nstored, 0, 0); /* 4create all producers and all consumers */ pthread_setconcurrency(nproducers + nconsumers); for (i = 0; i < nproducers; i++) { prodcount[i] = 0; pthread_create(&tid_produce[i], NULL, produce, &prodcount[i]); } for (i = 0; i < nconsumers; i++) { conscount[i] = 0; pthread_create(&tid_consume[i], NULL, consume, &conscount[i]); } /* 4wait for all producers and all consumers */ for (i = 0; i < nproducers; i++) { pthread_join(tid_produce[i], NULL); printf("producer count[%d] = %d\n", i, prodcount[i]); } for (i = 0; i < nconsumers; i++) { pthread_join(tid_consume[i], NULL); printf("consumer count[%d] = %d\n", i, conscount[i]); } sem_destroy(&shared.mutex); sem_destroy(&shared.nempty); sem_destroy(&shared.nstored); exit(0); } /* end main */ /* include produce */ void * produce(void *arg) { for ( ; ; ) { sem_wait(&shared.nempty); /* wait for at least 1 empty slot */ sem_wait(&shared.mutex); if (shared.nput >= nitems) { sem_post(&shared.nstored); /* let consumers terminate */ sem_post(&shared.nempty); sem_post(&shared.mutex); return(NULL); /* all done */ } shared.buff[shared.nput % NBUFF] = shared.nputval; printf("put: buff[%d]=%d\n",shared.nput % NBUFF,shared.nputval); shared.nput++; shared.nputval++; sem_post(&shared.mutex); sem_post(&shared.nstored); /* 1 more stored item */ *((int *) arg) += 1; } } /* end produce */ /* include consume */ void * consume(void *arg) { int i; for ( ; ; ) { sem_wait(&shared.nstored); /* wait for at least 1 stored item */ sem_wait(&shared.mutex); if (shared.nget >= nitems) { sem_post(&shared.nstored); sem_post(&shared.mutex); return(NULL); /* all done */ } i = shared.nget % NBUFF; if (shared.buff[i] != shared.ngetval) printf("error: buff[%d] = %d\n", i, shared.buff[i]); printf("get: buff[%d]=%d\n",i % NBUFF,i); shared.nget++; shared.ngetval++; sem_post(&shared.mutex); sem_post(&shared.nempty); /* 1 more empty slot */ *((int *) arg) += 1; } } /* end consume */
需要注意的就是必须有80行:sem_post(&shared.nstored);
当生产者生产完后,让每个生产者线程给nstored加1以给各个消费者线程接阻塞。不然消费者进程将永远阻塞在sem_wait(&shared.nstored)上
相关文章推荐
- UNIX网络编程
- UNIX网络编程
- 生产者消费者问题——Java方案
- UNIX网络编程 UNP 卷2 第一章
- unix网络编程(第三版)中的unp.h
- 线程同步-条件变量-unix网络编程
- unix网络编程之利用select 实现群发的功能
- Unix网络编程代码 第20章 广播
- UNIX网络编程学习(8)--服务器端显示客户端的IP地址和端口号
- Unix网络编程笔记(第四章)
- unix网络编程-第七章-小结
- unix网络编程之简介和运输层TCP/UDP
- Unix网络编程 chapter5 TCP回射服务器程序winsock改写
- unix网络编程--时间同步
- 生产者消费者问题
- 【UNIX网络编程】第三期 Socket编程简介
- 《unix网络编程》源码编译
- unix网络编程之基本套接口编程
- UNIX网络编程——网络数据包检测
- UNIX网络编程——TCP输出,UDP输出