标签:
一. 实验目的
实现一个c程序,该程序能模拟解决有限缓冲问题,其中消费者和生产者产生和消耗随机数
二.实验内容
元数据类型为buffer_item,大小为1000的数组,按环形队列处理
生产者不断执行如下两个操作:消费一个随机数,生产两个随机数
消费者不断执行如下两个操作:生产一个随机数,消费两个随机数
3.Pthead线程创建
使用pthread_create创建5个生产者线程,5个消费者线程,主程序等待所有线程退出
三. 实验环境
Ubuntu Gnome 14.04
MinGW 4.8.1
Codeblocks 13.12
四.实验结果
基本采用semaphore实现了题目要求,其中
psem用于标示是否可生产(数量是否超过缓冲区大小),初始量为1000,每次消费+1,
csem用于标示是否可消费,初始量为0,每次生产+1,
sem用于标示是否可以修改缓冲区
但是以下情况会发生,导致程序死锁:
例如:5个消费者生产5个随机数,随后消耗这5个随机数,则生产者无法先消耗随机数再生产
五.附录
调试心得:
1. 有限缓冲问题确实可能死锁
2. Pthread_create(tid,attr,func_name,arg)最后一个参数表示唯一传给线程的参数
3. Void *func_name(void *arg)return需要用pthread_exit(),这个函数的作用是,终止调用它的线程并返回一个指向某个对象的指针,但是直接调用exit(0)会使整个进程退出. 如果主线程调用了pthread_exit,那么它退出了,子线程也不会退出。如果是return 0则会直接退出.
4. 使用函数pthread_exit退出线程,这是线程的主动行为;由于一个进程中的多个线程是共享数据段的,因此通常在线程退出之后,退出线程所占用的资源并不会随着线程的终止而得到释放,但是可以用pthread_join()函数来同步并释放资源。在Linux中,默认情况下是在一个线程被创建后,必须使用此函数对创建的线程进行资源回收,但是可以设置Threads attributes来设置当一个线程结束时,直接回收此线程所占用的系统资源
5. 在线程函数在编译时,需要连接库函数, -lpthread
#include <stdio.h> #include <pthread.h> #include <semaphore.h> #include <cstdlib> #include <cstring> using namespace std; typedef int item; const int bsize = 1000; const int pnum = 5; const int cnum = 10; const int looptimes = 10000; sem_t sem,psem,csem; struct que{ item a[bsize]; int head,tail,n; que(){ memset(a,0,sizeof(a)); head=tail=n=0; } }q; void p(char * str,int num){ while(num--){ sem_wait(&psem); sem_wait(&sem); q.a[q.head]=rand()%10; q.n++; printf("%s: produce a[%d]:%d, now there is %d numbers in queue\n",str,q.head,q.a[q.head],q.n); q.head=(q.head+1)%bsize; sem_post(&csem); sem_post(&sem); } } void c(char *str,int num){ while(num--){ sem_wait(&csem); sem_wait(&sem); q.n--; printf("%s: consume a[%d]:%d, now there is %d numbers in queue\n",str,q.tail,q.a[q.tail],q.n); q.tail=(q.tail+1)%bsize; sem_post(&psem); sem_post(&sem); } } void * producer(void * arg){ for(int i=0;i<looptimes;i++){ c((char*)arg,1); p((char*)arg,2); } pthread_exit(0); } void * consumer(void * arg){ for(int i=0;i<looptimes;i++){ p((char*)arg,1); c((char*)arg,2); } pthread_exit(0); } int main(){ sem_init(&sem,0,1); sem_init(&psem,0,1000); sem_init(&csem,0,0); char pname[5][3]={"p1","p2","p3","p4","p5"}; char cname[5][3]={"c1","c2","c3","c4","c5"}; pthread_t ptid[5],ctid[5]; pthread_attr_t pattr[5],cattr[5]; for(int i=0;i<5;i++){ pthread_attr_init(pattr+i); pthread_create(ptid+i,pattr+i,producer,pname[i]); pthread_attr_init(cattr+i); pthread_create(ctid+i,cattr+i,consumer,cname[i]); } for(int i=0;i<5;i++){ pthread_join(ptid[i],NULL); pthread_join(ctid[i],NULL); } puts("end"); return 0; }
Operating System Concepts 项目:生产者-消费者问题 线程
标签:
原文地址:http://www.cnblogs.com/xuesu/p/4474496.html