windows编程实现生产者消费者问题

有四个生产者线程和四个消费者线程, 
生产者线程的操作;当生产一个产品时,自己的生产区中画一个矩形区域,存入公共空间时,自己空间的矩形移动到公共空间。 
消费者操作类似。 

我遇到的问题就是:当程序执行到生产者线程创建的时候,程序不再执行回调函数, 
下面是源代码:(这里面只是执行了生产操作,其他的尚未完成) 

//头文件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

你可能感兴趣的:(windows,struct,源代码,pascal,winapi)