理发师问题

来源:互联网 发布:java中的treeset 编辑:程序博客网 时间:2024/04/30 20:32
#include <Windows.h>#include <stdio.h>#include <process.h>#include <tchar.h>#include <time.h>#include <sys/timeb.h>#include <sys/types.h>#define CHAIR_SIZE 2#define BARBER_SIZE 2#define CUSTOMER_THREAD_SIZE 2//当前“椅子”坐了哪些顾客int chair[CHAIR_SIZE];//mutex用来锁定“椅子”,避免多个线程同时对“椅子”进行读写HANDLE mutex, empty, full;DWORD WINAPI BarberThread(PVOID pvParam);//理发师线程DWORD WINAPI CustomerThread(PVOID pvParam);//生成顾客的线程void initRand();int main(int argc, char **argv){//对变量先进行初始化memset(chair, 0, sizeof(chair));mutex = CreateMutex(NULL, 0, NULL);HANDLE flag;DWORD threadId;for (int i = 0; i < BARBER_SIZE; i++){flag = CreateThread(NULL, 0, BarberThread, NULL, 0, &threadId);if (flag)printf("Barber thread %d created.\n", threadId);elseprintf("Error %d while creating barber thread\n", GetLastError());CloseHandle(flag);}for (int i = 0; i < CUSTOMER_THREAD_SIZE; i++){flag = CreateThread(NULL, 0, CustomerThread, NULL, 0, &threadId);if (flag)printf("Customer thread %d created.\n", threadId);elseprintf("Error %d while creating custom thread\n", GetLastError());CloseHandle(flag);}empty = CreateSemaphore(NULL, 2, 2, NULL);full = CreateSemaphore(NULL, 0, 2, NULL);while (true);return 0;}DWORD WINAPI BarberThread(PVOID pvParam){int threadId = GetCurrentThreadId();DWORD rst;DWORD r = 1000;while (true){initRand();//取系统当前时间做为生成随机数的种子rst = WaitForSingleObject(full, 1000);//等待一段时间,如果没有“顾客”来,就去睡觉switch (rst){case WAIT_OBJECT_0:WaitForSingleObject(mutex, INFINITE);printf("customer %d is moved to barber %d\n", chair[0], threadId);chair[0] = chair[1];//顾客有先来后到,保证下一个去理发的顾客是紧随刚刚那一个去理发的人来的if (chair[1] != 0)printf("customer %d is moved to chair 0\n", chair[1]);chair[1] = 0;//这一句必须放在下一句之前。如果不这样,假设两个barber线程都到这里//先把mutex释放了,而没有先releasesemaphore,那么如果这时候调用//customerthread,就会造成有“空座位”而“顾客”坐不了的情况ReleaseSemaphore(empty, 1, NULL);ReleaseMutex(mutex);Sleep( (rand()%2+3)*1000 );//理发中,理发时间随机3-5秒break;case WAIT_TIMEOUT:printf("barber %d waiting for the next customer\n", threadId);Sleep(0);//主动放弃剩余的时间片,去“睡觉”break;case WAIT_FAILED:break;}}}int customerId = 1;//顾客的IDDWORD WINAPI CustomerThread(PVOID pvParam){DWORD rst;while (true){//initRand();rst = WaitForSingleObject(empty, 10);//顾客只会等待较短时间,如果没有椅子坐,就会离开switch (rst){case WAIT_OBJECT_0:WaitForSingleObject(mutex, INFINITE);if (chair[0] == 0){chair[0] = customerId;printf("customer %d sitting on chair 0\n", customerId);}else{chair[1] = customerId;printf("customer %d sitting on chair 1\n", customerId);}customerId++;ReleaseMutex(mutex);ReleaseSemaphore(full, 1, NULL);break;case WAIT_TIMEOUT:WaitForSingleObject(mutex, INFINITE);printf("No chair for customer %d, leaving\n", customerId++);ReleaseMutex(mutex);break;case WAIT_FAILED:break;}Sleep((rand() % 3 + 1) * 1000);//每隔一段时间产生一个新顾客}}void initRand(){// 如果支持高性能精度计数器,则使用其初始化随机种子(微秒级)LARGE_INTEGER nFrequency;if (::QueryPerformanceFrequency(&nFrequency)){LARGE_INTEGER nStartCounter;QueryPerformanceCounter(&nStartCounter);srand((unsigned)nStartCounter.LowPart);}else // 否则使用当前系统时间初始化随机种子(毫秒级){_timeb stb;_ftime(&stb);srand((unsigned)stb.millitm);}}

0 0
原创粉丝点击