有四个生产者线程和四个消费者线程, 生产者线程的操作;当生产一个产品时,自己的生产区中画一个矩形区域,存入公共空间时,自己空间的矩形移动到公共空间。 消费者操作类似。 我遇到的问题就是:当程序执行到生产者线程创建的时候,程序不再执行回调函数, 下面是源代码:(这里面只是执行了生产操作,其他的尚未完成) //头文件header.h //在此文件中主要定义程序中所需要的图形界面的点的集合,以及所要使用的画刷、画笔 #ifndef _HEADER #define _HEADER #include<windows.h> #include<stdio.h> //////////////////////////////////////////////////////////////////////////////////////////////////////////// //定义窗口中所需要的画笔 //HPEN black_pen = CreatePen(PS_SOLID,2,RGB(100,100,100)); //用于画窗口边框 HPEN red_pen = CreatePen(PS_SOLID,2,RGB(255,0,0)); //用于画窗口内部的线条 HPEN produce_pen = CreatePen(PS_SOLID,1,RGB(0,230,180)); //用于画产品的边线 //定义窗口中所需要的画刷 HBRUSH bk_brush = CreateSolidBrush(RGB(137,156,205)); //用于填充公共区域的空间 HBRUSH green_brush = CreateSolidBrush(RGB(0,255,0)); //用于填充生产者的空间 HBRUSH yellow_brush = CreateSolidBrush(RGB(255,255,0)); //用于填充消费者的空间 HBRUSH produce_brush = CreateSolidBrush(RGB(0,230,180)); //用于填充产品区域 ///////////////////////////////////////////////////////////////////////////////////////////////////////////// //定义生产者消费者问题中所需要的信号量以及各个变量 //变量定义 const unsigned short SIZE_OF_BUFFER = 32; //缓冲区的大小 //int g_buffer[SIZE_OF_BUFFER]; //开辟缓冲区,用数组表示,可看成一个循环队列 unsigned short ProductID = 0; //新生产出来的产品的ID号 unsigned short ConsumeID = 0; //被消耗的产品的ID号 bool g_continue = 1; //控制线程的运行:1表示继续运行,0表示停止运行 //信号量定义 HANDLE g_hMutex; //线程间的互斥信号 HANDLE g_hFullSemaphore; //资源信号量,表示缓冲区已满 HANDLE g_hEmptySemaphore; //资源信号量,表示缓冲区为空 //生产者、消费者的个数 const unsigned short PRODUCERS_COUNT = 4; //生产者的个数 const unsigned short CONSUMERS_COUNT = 4; //消费者的个数 const unsigned short THREADS_COUNT = PRODUCERS_COUNT + CONSUMERS_COUNT; //线程的总个数 //生产者、消费者线程ID号定义 HANDLE hThreads[THREADS_COUNT]; //各个线程的句柄 DWORD ProducerID[CONSUMERS_COUNT]; //生产者线程的标识 DWORD ConsumerID[PRODUCERS_COUNT]; //消费者线程的标识 typedef struct param{ int num; HWND hWnd; }; ///////////////////////////////////////////////////////////////////////////////////////////////////////////// //定义窗口中的各个定点 //窗口的坐标定义 //POINT WndPoint[4] = { // {100,100}, // {800,100}, // {800,600}, // {100,600} //} //公共区坐标定义 POINT ShareSpace[4] = { {100,100}, {800,100}, {800,490}, {100,490} }; //生产者空间坐标定义 POINT ProduceSpace[4] = { {100,490}, {450,490}, {450,600}, {100,600} }; //消费者空间坐标定义 POINT ConsumerSpace[4] = { {450,490}, {800,490}, {800,600}, {450,600} }; #endif //主函数开始 #include"header.h" //画窗口中的矩形区域 void DrawRec(HWND hWnd,HPEN pen,HBRUSH brush,POINT *point,int n) { HDC hdc; hdc = GetDC(hWnd); SelectObject(hdc,pen); SelectObject(hdc,brush); Polygon(hdc,point,n); SelectObject(hdc,pen); SelectObject(hdc,brush); ReleaseDC(hWnd,hdc); } //生产产品 void Produce(param P) { HDC hdc; hdc = GetDC(P.hWnd); // POINT CONSUME[4] = { // {105+88*(num - 1),495}, // {105+88*(num - 1)+70,495}, // {105+88*(num - 1)+70,565}, // {195+88*(num - 1),565} //}; // DrawRec(hWnd,produce_pen,produce_brush,CONSUME,4); TextOut(hdc,105,495,"HELLO",strlen("HELLO")); ReleaseDC(P.hWnd,hdc); } //将产品送入缓冲区 void AddToBuffer(HWND hWnd) { } //取出一件产品 void Take(HWND hWnd) { } //消费一件产品 void Consume(HWND hWnd) { } //生产者得操作 DWORD WINAPI Producer(param P) { while(g_continue) { //资源信号量得操作 WaitForSingleObject(g_hFullSemaphore,INFINITE); //满缓冲区P操作 WaitForSingleObject(g_hMutex,INFINITE); //互斥信号P操作 Produce(P); AddToBuffer(P.hWnd); ReleaseMutex(g_hMutex); //释放互斥信号,V操作 ReleaseSemaphore(g_hEmptySemaphore,1,NULL); //释放空缓冲区操作,V操作 } return 0; } //消费者操作 void Consumer(HWND hWnd) { while(g_continue) { //资源信号量操作 WaitForSingleObject(g_hEmptySemaphore,INFINITE); WaitForSingleObject(g_hMutex,INFINITE); Take(hWnd); Consume(hWnd); ReleaseMutex(g_hMutex); ReleaseSemaphore(g_hFullSemaphore,1,NULL); } } //创建生产者线程 void CreatePT(HWND hWnd) { param P; P.hWnd= hWnd; for(int i = 0;i < PRODUCERS_COUNT;++i) { P.num = i; hThreads[i] = CreateThread(NULL,0,(LPTHREAD_START_ROUTINE)Producer,&P,0,&ProducerID[i]); if(hThreads[i] == NULL) g_continue = 0; } } //创建消费者线程 void CreateCT(HWND hWnd) { for(int j = 0;j<CONSUMERS_COUNT;++j) { hThreads[j+PRODUCERS_COUNT]=CreateThread(NULL,0,(LPTHREAD_START_ROUTINE)Consumer,NULL,0,&ConsumerID[j]); if(hThreads[j] == NULL) g_continue = 0; } } //回调函数体 long FAR PASCAL WindowsProc(HWND hWnd,UINT message,WPARAM wParam,LPARAM lParam) { switch(message) { case WM_PAINT: { //窗口修饰 HDC hdc; PAINTSTRUCT ps; hdc=BeginPaint(hWnd,&ps); hdc = GetDC(hWnd); DrawRec(hWnd,red_pen,bk_brush,ShareSpace,4); //画共享空间区域 DrawRec(hWnd,red_pen,green_brush,ProduceSpace,4); //画生产者空间区域 DrawRec(hWnd,red_pen,yellow_brush,ConsumerSpace,4); //画消费者空间区域 ///////////////////////////////////////////////////////////////////// //显示文字提示信息以及作者信息 TextOut(hdc,420,30,"生产者消费者问题",strlen("生产者消费者问题")); TextOut(hdc,650,35,"姓名:冯冬冬",strlen("姓名:冯冬冬")); TextOut(hdc,650,55,"学号:1107090109",strlen("学号:1107090109")); TextOut(hdc,650,75,"院系:计科系网本一班",strlen("院系:计科系网本一班")); TextOut(hdc,430,110,"公共空间",strlen("公共空间")); TextOut(hdc,250,580,"生产者",strlen("生产者")); TextOut(hdc,600,580,"消费者",strlen("消费者")); ////////////////////////////////////////////////////////////////////// //区分文字区与图形区 SelectObject(hdc,red_pen); MoveToEx(hdc,100,130,NULL); LineTo(hdc,800,130); MoveToEx(hdc,100,570,NULL); LineTo(hdc,800,570); ////////////////////////////////////////////////////////////////////// //区分不同的消费者和生产者 int temp = 188; while(temp < 450) //此过程一次性画两条线 { MoveToEx(hdc,temp,490,NULL); LineTo(hdc,temp,570); MoveToEx(hdc,900-temp,490,NULL); LineTo(hdc,900-temp,570); //900-temp:即900-(temp - 100) temp += 88; } SelectObject(hdc,red_pen); ReleaseDC(hWnd,hdc); EndPaint(hWnd,&ps); } break; case WM_CLOSE: { int result = MessageBox(hWnd,"确定要关闭窗口吗??","关闭窗口",MB_YESNO | MB_ICONQUESTION); if(result == IDYES) { ExitThread(0); return DefWindowProc(hWnd,message,wParam,lParam); //DestroyWindow(hWnd); } } break; case WM_DESTROY: ExitThread(0); PostQuitMessage(0); return 0; } return DefWindowProc(hWnd,message,wParam,lParam); } //Win32主函数 //////////////////////////////////////////////////////////////////////////////////// int WINAPI WinMain( HINSTANCE hInstance, // handle to current instance HINSTANCE hPrevInstance, // handle to previous instance LPSTR lpCmdLine, // command line int nCmdShow) // show state { MSG msg; //定义一个消息对象 HWND hWnd; //窗口句柄 WNDCLASS wc; //定义窗口 wc.style = CS_HREDRAW | CS_VREDRAW; //支持水平和垂直窗口 wc.lpfnWndProc = WindowsProc; //定义相应信息的处理函数 wc.cbClsExtra = 0; //附加内存空间 wc.cbWndExtra = 0; //附加内存空间 wc.hInstance = hInstance; //窗口的实例化句柄 wc.hIcon = NULL; //窗口的图标 wc.hCursor = LoadCursor(NULL,IDC_ARROW); //设置窗口鼠标的形状 wc.hbrBackground = (HBRUSH) GetStockObject(GRAY_BRUSH); //背景刷及背景颜色 wc.lpszMenuName = NULL; //窗口是否有菜单 wc.lpszClassName = "producer"; //窗口的类名称,全文必须一致 RegisterClass(&wc); //注册窗口句柄 hWnd = CreateWindowEx(WS_EX_TOPMOST, //窗口总显示在顶部 "producer", //窗口类名 "Producer And Consumer", //窗口标题 WS_OVERLAPPEDWINDOW, //窗口风格 100, //窗口左上角的x的位置 100, //窗口左上角的y的位置 900, //窗口宽度初始化 700, //窗口高度的初始化 NULL, //父窗口句柄 NULL, //窗口菜单句柄 hInstance, //窗口事例句柄 NULL); //附加信息 if( ! hWnd) //判断窗口是否创建成功 { return FALSE; } ShowWindow(hWnd,nCmdShow); //显示窗口 UpdateWindow(hWnd); //更新窗口 while(GetMessage(&msg,NULL,0,0)) { TranslateMessage(&msg); DispatchMessage(&msg); } // while(PeekMessage(&msg,NULL,0,0,PM_REMOVE)) // { // if(msg.message == WM_QUIT) // { // break; // } // TranslateMessage(&msg); // DispatchMessage(&msg); // } //////////////////////////////////////////////////////////////////////////////////////// //开始创建生产者、消费者线程 //创建互斥信号量 g_hMutex=CreateMutex(NULL,FALSE,NULL); //创建资源信号量 g_hFullSemaphore=CreateSemaphore(NULL,SIZE_OF_BUFFER-1,SIZE_OF_BUFFER-1,NULL); g_hEmptySemaphore=CreateSemaphore(NULL,0,SIZE_OF_BUFFER-1,NULL); CreatePT(hWnd); CreateCT(hWnd); while(WM_CLOSE) { g_continue = 0; } return 1; }
原文地址:http://www.oschina.net/question/124134_21696