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

冯冬冬 发布于 2011/06/12 13:34
阅读 1K+
收藏 0
有四个生产者线程和四个消费者线程,
生产者线程的操作;当生产一个产品时,自己的生产区中画一个矩形区域,存入公共空间时,自己空间的矩形移动到公共空间。
消费者操作类似。

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

//头文件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;
}
加载中
返回顶部
顶部