有没有用c++写过多线程问题的大神,一个简单的叫号系统线程之间交互出现了一些问题
程序代码:
/ BankHandle.cpp : 定义控制台应用程序的入口点。 // #include <stdio.h> #include <stdlib.h> #include <Windows.h> #include <string> #include <queue> using namespace std; #define CHAIR_NUM 5 //椅子数 #define ARRIVE_TIME 5000 // #define DOSERIV_TIME 5000 //办理业务时长 int num_empty_chair=CHAIR_NUM; //等待区椅子数 HANDLE hFull=CreateSemaphore(NULL, 0,CHAIR_NUM,NULL); //信号量 HANDLE hEmpty=CreateSemaphore(NULL, CHAIR_NUM,CHAIR_NUM,NULL); //信号量 HANDLE hDoor= CreateEvent(NULL, TRUE,FALSE, NULL); //开门事件,人工重置事件 HANDLE hDoOver= CreateEvent(NULL, FALSE,FALSE, NULL); //办理业务结束事件,自动重置事件 HANDLE hDoBye = CreateEvent(NULL, FALSE,FALSE, NULL); HANDLE *t;//顾客线程 HANDLE sw[5];//服务窗口线程 int in=-1,out=0; int CCount=0; //银行中的所有顾客数,包括正在办理业务的 HANDLE hChairs[CHAIR_NUM]; //事件数组,每把椅子对应一个事件 HANDLE mutex; HANDLE numPlate[10];//叫号 CRITICAL_SECTION cs; //临界区 HANDLE custMutex[10]; typedef struct SParam { int Custid; char Type; SParam *next; }cust,*sParam; typedef struct SWParam { int SWid; char SWType; SParam *item; }SerWin,*swParam; DWORD WINAPI SeriverWindows(LPVOID p) { SerWin *swparam= (SerWin*)p; SetEvent(hDoor); while(true) { if(WaitForSingleObject( hFull,1)==WAIT_TIMEOUT) //检查等候室有没有顾客 { printf("\n\n\t\t\t\t\t%c%d窗口:没有顾客了,整理一下资料吧......",(*swparam).SWType,(*swparam).SWid); } WaitForSingleObject(hFull,INFINITE); WaitForSingleObject(mutex,INFINITE); //申请叫号,如果其他柜员在叫,那么等待(柜员叫号要互斥) int plateNo = out+1; printf("\n\n\t\t%c%d窗口:请%d号顾客来办理业务办理....\n",(*swparam).SWType,(*swparam).SWid,plateNo); SetEvent(hChairs[out]); out=(out+1)%CHAIR_NUM; ResetEvent(hChairs[out]); ReleaseMutex(mutex); Sleep(DOSERIV_TIME); //办理业务计时 printf("\n\n\t\t\t\t\t%c%d窗口:办理完了,顾客%d您看看怎么样?",(*swparam).SWType,(*swparam).SWid,plateNo); SetEvent(hDoOver); WaitForSingleObject(hDoBye,INFINITE); printf("\n\n\t\t\t\t\t%c%d窗口:再见%d顾客,欢迎再来!!",(*swparam).SWType,(*swparam).SWid,plateNo); ReleaseMutex(hDoBye); } } DWORD WINAPI Customer(LPVOID p) { cust *sparam= (cust*)p; int c_num;//存储要占用的椅子号 WaitForSingleObject(mutex,INFINITE); ReleaseMutex(mutex); printf("\n来了顾客%d,号码为%c%d",(*sparam).Custid,(*sparam).Type,(*sparam).Custid); if(WaitForSingleObject(hDoor,1)==WAIT_TIMEOUT) { printf("\n顾客%d:银行还没有开门啊,等一会吧......",(*sparam).Custid); if(WaitForSingleObject(hDoor,10000)==WAIT_TIMEOUT) { printf("\n顾客%d::这么长时间都还不开门,明天再来吧!!", (*sparam).Custid); return 0; } } EnterCriticalSection(&cs); CCount++; //顾客数增加 if(WaitForSingleObject(hEmpty,1)==WAIT_TIMEOUT) { printf("\n顾客%d :好多人啊,连座位都没有,下次再来吧......",(*sparam).Custid); LeaveCriticalSection(&cs); return 0; } printf("\n顾客%d :幸好还有%d个座位,等一会吧......",(*sparam).Custid,CHAIR_NUM+2-CCount); in=(in+1)%CHAIR_NUM; c_num=in; LeaveCriticalSection(&cs); ReleaseSemaphore(hFull,1,NULL); WaitForSingleObject(hChairs[c_num],INFINITE); //坐在椅子上等待 printf("\n顾客%d :终于轮到我了!", (*sparam).Custid); ReleaseSemaphore(hEmpty,1,NULL); printf("\n顾客%d :开始办理业务......", (*sparam).Custid); WaitForSingleObject(hDoOver,INFINITE); printf("\n顾客%d:很好,谢谢,再见!", (*sparam).Custid); ReleaseMutex(hDoOver); SetEvent(hDoBye); EnterCriticalSection(&cs); CCount--; LeaveCriticalSection(&cs); return 0; } void main() { sParam p=new cust[11]; //顾客数组 swParam s = new SerWin[5]; //服务窗口数组 InitializeCriticalSection(&cs); //进入临界区 for (int i = 1; i <= CHAIR_NUM ; i++) hChairs[i] =CreateEvent(NULL,FALSE,FALSE, NULL); //自动重置事件 mutex = CreateMutex(NULL,FALSE,NULL); for(int i = 1;i<=4;i++) { s[i].SWid=i; s[i].SWType='A'; sw[i]=CreateThread(NULL, 0, SeriverWindows,(LPVOID)(&s[i]), 0, NULL ); //服务线程线程 custMutex[i] = CreateSemaphore(NULL, 0, 1, NULL); } t=new HANDLE[11]; Sleep(2000); for(int i=1;i<=10;i++) { p[i].Custid = i; p[i].Type = 'A'; t[i]=CreateThread(NULL, 0, Customer,(LPVOID)(&p[i]),0, NULL ); //顾客来 numPlate[i] = t[i]; Sleep(2000); } WaitForMultipleObjects(11, t, TRUE, INFINITE); //printf("结束"); DeleteCriticalSection(&cs); system("pause"); }