PV操作(哲学家问题和生产者-消费者问题).doc

上传人:豆**** 文档编号:23970608 上传时间:2022-07-03 格式:DOC 页数:47 大小:211KB
返回 下载 相关 举报
PV操作(哲学家问题和生产者-消费者问题).doc_第1页
第1页 / 共47页
PV操作(哲学家问题和生产者-消费者问题).doc_第2页
第2页 / 共47页
点击查看更多>>
资源描述

《PV操作(哲学家问题和生产者-消费者问题).doc》由会员分享,可在线阅读,更多相关《PV操作(哲学家问题和生产者-消费者问题).doc(47页珍藏版)》请在taowenge.com淘文阁网|工程机械CAD图纸|机械工程制图|CAD装配图下载|SolidWorks_CaTia_CAD_UG_PROE_设计图分享下载上搜索。

1、Four short words sum up what has lifted most successful individuals above the crowd: a little bit more.-author-datePV操作(哲学家问题和生产者-消费者问题)PV操作(哲学家问题和生产者-消费者问题)PV操作(哲学家问题)给每个哲学家编号,规定奇数号的哲学家先拿他的左筷子,然后再去拿他的右筷子;而偶数号的哲学家则相反。这样总可以保证至少有一个哲学家可以进餐。#include #include #include #include #include using namespace st

2、d; DWORD WINAPI philosopher(LPVOID lpParameter); void thinking(int); void eating(int); void waiting(int); void print(int ,const char *); /全局变量 CRITICAL_SECTION crout;/这个变量用来保证输出时不会竞争 CRITICAL_SECTION fork5;/定义五个临界变量,代表五更筷子 int main(int argc,char *argv) HANDLE hthread5; int i; int arg5; int count = 5

3、; long a=0; unsigned long retval; InitializeCriticalSection(&crout); /初始化临界变量 for(i=0;i5;i+) InitializeCriticalSection(fork + i); /创建五个哲学家 for(i = 0; i5;i+) argi = i; hthreadi = CreateThread(NULL, 0, philosopher, (void*)(arg+i), 0, NULL); for(a=0;a30000000;a+); if( hthreadi = INVALID_HANDLE_VALUE)/如

4、果线程创建失败返回-1 cerr error while create thread i endl; cerr error code : GetLastError() endl; /等待所有线程结束 retval = WaitForMultipleObjects(5,hthread,true,INFINITE);/等待多个线程 for(a=0;a30000000;a+); if(retval = WAIT_FAILED) cerr wait error,error code: GetLastError()endl; for(i = 0; i5;i+) for(a=0;a30000000;a+)

5、; if(CloseHandle(hthreadi) = false)/关闭句柄 cerr error while close thread iendl; cerr error code: GetLastError()endl; return 0; DWORD WINAPI philosopher(LPVOID lpParameter) long a=0; int n = (int *)lpParameter)0; for(a=0;a30000000;a+); print(n, is in!); /srand(time(NULL); while(true) thinking(n); waiti

6、ng(n); eating(n); print(n, is out!); return n; void thinking(int k) long a=0;for(a=0;a30000000;a+); print(k, is thinking.); Sleep(1); /Sleep(rand() %100) *5); void eating(int k) long a=0;for(a=0;a30000000;a+); print(k, is eating.); /Sleep(rand()%100) *5); Sleep(1); LeaveCriticalSection(fork + (k+1)%

7、5);/放下右边的筷子 /print(k, give left); LeaveCriticalSection(fork + k);/放下左边的筷子 /print(k, give right); void waiting(int k) long a=0;for(a=0;a30000000;a+); print(k, is waiting.); Sleep(1); EnterCriticalSection(fork + k);/获得左边的筷子 /print(k, take left); EnterCriticalSection(fork + (k + 1)%5);/获得右边的筷子 /print(k

8、, take right); void print(int who,const char *str) long a=0;for(a=0;a30000000;a+); EnterCriticalSection(&crout); coutprocess whostrendl; LeaveCriticalSection(&crout); 操作截图PV操作(生产者-消费者问题)解决方法一:实现思想,我们在产生足够的产品后,唤醒消费者把生产的产品全部消耗,让后在唤醒生产者生产商品。 /* 用信号量解决生产者消费者问题 */解决方法生产者生产10间产品,唤醒消费者,消费完后,唤醒生产者 #include

9、#define N 10 typedef int semaphore; /* 信号量是一种特殊的整型变量 */ semaphore mutex=1; /* 互斥访问 */ semaphore empty=N; /* 记录缓冲区中空的槽数 */ semaphore full=0; /* 记录缓冲区中满的槽数*/ semaphore bufN; /* 有N个槽数的缓冲区bufN,并实现循环缓冲队列 */ semaphore front=0, rear=0; void p(semaphore *x) /* p操作 */ *x=(*x)-1; void v(semaphore *y) /* v操作 *

10、/ *y=(*y)+1; void produce_item(int *item_ptr) /*printf(produce an itemn);*/ *item_ptr=m; /* m is man满 */ void enter_item(int x) front=(front+1)%N; buffront=x; printf(enter_item %c to buf%dn, buffront, front); void remove_item(int *yy) rear=(rear+1)%N; printf(remove_item %c from buf%d, bufrear, rear)

11、; *yy=bufrear; bufrear=k; /* k is kong空 */ printf( so the buf%d changed to empty-%cn, rear, bufrear); void consume_item(int y) printf(cosume the item :the screem print %cn, y); void producer(void); void consumer(void); /* 生产者 */ void producer(void) int item; while(1) produce_item(&item); p(&empty);

12、/* 递减空槽数 */ p(&mutex); /* 进入临界区 */ enter_item(item); /* 将一个新的数据项放入缓冲区 */ v(&mutex); /* 离开临界区 */ v(&full); /* 递增满槽数 */ if(full=N) /* 若缓冲区满的话,唤醒消费者进程 */ consumer(); /* 消费者 */ void consumer(void) int get_item; while(1) p(&full); /* 递减满槽数 */ p(&mutex); /* 进入临界区 */ remove_item(&get_item); /* 从缓冲区中取走一个数据项

13、 */ v(&mutex); /* 离开临界区 */ v(&empty); /* 递增空槽数 */ consume_item(get_item); /* 对数据项进行操作(消费)*/ if(empty=N) /* 若缓冲区全空的话,唤生产者进程 */ producer(); /* 调用生产者消费者进程实现进程间同步 */ main() producer(); return 0; 生产者消费者问题解决方法二:因为实际情况是生产消费速度不会一致,也不会想方法一一样,消费完后在生产。我们生产者要保持满足消费者的需求。调整下面的数值,可以发现,当生产者个数多于消费者个数时,生产速度快,生产者经常等待消

14、费者;反之,消费者经常等待,可以保证消费者可以一直消费。实现代码:#include #include const unsigned short SIZE_OF_BUFFER = 10; /缓冲区长度unsigned short ProductID = 0; /产品号unsigned short ConsumeID = 0; /将被消耗的产品号unsigned short in = 0; /产品进缓冲区时的缓冲区下标unsigned short out = 0; /产品出缓冲区时的缓冲区下标int g_bufferSIZE_OF_BUFFER; /缓冲区是个循环队列bool g_continue

15、 = true; /控制程序结束HANDLE g_hMutex; /用于线程间的互斥HANDLE g_hFullSemaphore; /当缓冲区满时迫使生产者等待HANDLE g_hEmptySemaphore; /当缓冲区空时迫使消费者等待DWORD WINAPI Producer(LPVOID); /生产者线程DWORD WINAPI Consumer(LPVOID); /消费者线程int main() /创建各个互斥信号 g_hMutex = CreateMutex(NULL,FALSE,NULL); g_hFullSemaphore = CreateSemaphore(NULL,SIZ

16、E_OF_BUFFER-1,SIZE_OF_BUFFER-1,NULL); g_hEmptySemaphore = CreateSemaphore(NULL,0,SIZE_OF_BUFFER-1,NULL); /调整下面的数值,可以发现,当生产者个数多于消费者个数时, /生产速度快,生产者经常等待消费者;反之,消费者经常等待 const unsigned short PRODUCERS_COUNT = 3; /生产者的个数 const unsigned short CONSUMERS_COUNT = 1; /消费者的个数 /总的线程数 const unsigned short THREADS_

17、COUNT = PRODUCERS_COUNT+CONSUMERS_COUNT; HANDLE hThreadsPRODUCERS_COUNT; /各线程的handle DWORD producerIDCONSUMERS_COUNT; /生产者线程的标识符 DWORD consumerIDTHREADS_COUNT; /消费者线程的标识符 /创建生产者线程 for (int i=0;iPRODUCERS_COUNT;+i) hThreadsi=CreateThread(NULL,0,Producer,NULL,0,&producerIDi); if (hThreadsi=NULL) retur

18、n -1; /创建消费者线程 for ( int i=0;iCONSUMERS_COUNT;+i) hThreadsPRODUCERS_COUNT+i=CreateThread(NULL,0,Consumer,NULL,0,&consumerIDi); if (hThreadsi=NULL) return -1; while(g_continue) if(getchar() /按回车后终止程序运行 g_continue = false; return 0;/生产一个产品。简单模拟了一下,仅输出新产品的ID号void Produce() std:cerr Producing +ProductID

19、 . ; std:cerr Succeed std:endl;/把新生产的产品放入缓冲区void Append() std:cerr Appending a product . ; g_bufferin = ProductID; in = (in+1)%SIZE_OF_BUFFER; std:cerr Succeed std:endl; /输出缓冲区当前的状态 for (int i=0;iSIZE_OF_BUFFER;+i) std:cout i : g_bufferi; if (i=in) std:cout - 生产; if (i=out) std:cout - 消费; std:cout s

20、td:endl; /从缓冲区中取出一个产品void Take() std:cerr Taking a product . ; ConsumeID = g_bufferout; out = (out+1)%SIZE_OF_BUFFER; std:cerr Succeed std:endl; /输出缓冲区当前的状态 for (int i=0;iSIZE_OF_BUFFER;+i) std:cout i : g_bufferi; if (i=in) std:cout - 生产; if (i=out) std:cout - 消费; std:cout std:endl; /消耗一个产品void Cons

21、ume() std:cerr Consuming ConsumeID . ; std:cerr Succeed std:endl;/生产者DWORD WINAPI Producer(LPVOID lpPara) while(g_continue) WaitForSingleObject(g_hFullSemaphore,INFINITE); WaitForSingleObject(g_hMutex,INFINITE); Produce(); Append(); Sleep(1500); ReleaseMutex(g_hMutex); ReleaseSemaphore(g_hEmptySemaphore,1,NULL); return 0;/消费者DWORD WINAPI Consumer(LPVOID lpPara) while(g_continue) WaitForSingleObject(g_hEmptySemaphore,INFINITE); WaitForSingleObject(g_hMutex,INFINITE); Take(); Consume(); Sleep(1500); ReleaseMutex(g_hMutex); ReleaseSemaphore(g_hFullSemaphore,1,NULL); return 0;运行结果:-

展开阅读全文
相关资源
相关搜索

当前位置:首页 > 教育专区 > 小学资料

本站为文档C TO C交易模式,本站只提供存储空间、用户上传的文档直接被用户下载,本站只是中间服务平台,本站所有文档下载所得的收益归上传人(含作者)所有。本站仅对用户上传内容的表现方式做保护处理,对上载内容本身不做任何修改或编辑。若文档所含内容侵犯了您的版权或隐私,请立即通知淘文阁网,我们立即给予删除!客服QQ:136780468 微信:18945177775 电话:18904686070

工信部备案号:黑ICP备15003705号© 2020-2023 www.taowenge.com 淘文阁