您的位置:首页 > 其它

windows下多线程(生产者消费者问题:3个生产者,一个消费者,4个缓冲区)

2014-12-02 00:19 465 查看
原作者提供源码为两种情况:

第一种:1生产者1消费者1缓冲区

第二种:1生产者 2消费者 4缓冲区

========================下面为修改作者源码得到的 3个生产者1个消费者4个缓冲区的情况==================

//1生产者 2消费者 4缓冲区
#include <stdio.h>
#include <process.h>
#include <windows.h>
//设置控制台输出颜色
BOOL SetConsoleColor(WORD wAttributes)
{
HANDLE hConsole = GetStdHandle(STD_OUTPUT_HANDLE);
if (hConsole == INVALID_HANDLE_VALUE)
return FALSE;

return SetConsoleTextAttribute(hConsole, wAttributes);
}
const int END_PRODUCE_NUMBER = 9;  //生产产品个数
const int BUFFER_SIZE = 4;          //缓冲区个数
int g_Buffer[BUFFER_SIZE];          //缓冲池
int g_i, g_j;
//信号量与关键段
CRITICAL_SECTION g_cs;
HANDLE g_hSemaphoreBufferEmpty, g_hSemaphoreBufferFull;

int data=0;
//生产者线程函数
unsigned int __stdcall ProducerThreadFun(PVOID pM)
{
//for (int i = 1; i <= END_PRODUCE_NUMBER; i++)
//{
while(data<END_PRODUCE_NUMBER)
{
//等待有空的缓冲区出现
WaitForSingleObject(g_hSemaphoreBufferEmpty, INFINITE);

//互斥的访问缓冲区
EnterCriticalSection(&g_cs);
if(data==END_PRODUCE_NUMBER)
{
LeaveCriticalSection(&g_cs);
break;
}
data=data+1;
g_Buffer[g_i] = data;
//printf("生产者在缓冲池第%d个缓冲区中投放数据%d\n", g_i, g_Buffer[g_i]);
printf("编号为%d的生产者在缓冲池中第%d个缓冲区中投放数据%d\n", GetCurrentThreadId(), g_i, g_Buffer[g_i]);
g_i = (g_i + 1) % BUFFER_SIZE;
LeaveCriticalSection(&g_cs);
Sleep(50);
//通知消费者有新数据了
ReleaseSemaphore(g_hSemaphoreBufferFull, 1, NULL);
}
/*    } */
printf("生产者完成任务,线程结束运行\n");
return 0;
}
//消费者线程函数
unsigned int __stdcall ConsumerThreadFun(PVOID pM)
{
while (true)
{
//等待非空的缓冲区出现
WaitForSingleObject(g_hSemaphoreBufferFull, INFINITE);

//互斥的访问缓冲区
EnterCriticalSection(&g_cs);
SetConsoleColor(FOREGROUND_GREEN);
/*printf("  编号为%d的消费者从缓冲池中第%d个缓冲区取出数据%d\n", GetCurrentThreadId(), g_j, g_Buffer[g_j]); */
printf("  编号为%d的消费者从缓冲池第%d个缓冲区取出数据%d\n",GetCurrentThreadId(), g_j, g_Buffer[g_j]);
SetConsoleColor(FOREGROUND_RED | FOREGROUND_GREEN | FOREGROUND_BLUE);
if (g_Buffer[g_j] == END_PRODUCE_NUMBER)//结束标志
{
LeaveCriticalSection(&g_cs);
//通知其它消费者有新数据了(结束标志)
//ReleaseSemaphore(g_hSemaphoreBufferFull, 1, NULL);
break;
}
g_j = (g_j + 1) % BUFFER_SIZE;
LeaveCriticalSection(&g_cs);

Sleep(50); //some other work to do

ReleaseSemaphore(g_hSemaphoreBufferEmpty, 1, NULL);
}
SetConsoleColor(FOREGROUND_GREEN);
printf("  编号为%d的消费者收到通知,线程结束运行\n", GetCurrentThreadId());
SetConsoleColor(FOREGROUND_RED | FOREGROUND_GREEN | FOREGROUND_BLUE);
return 0;
}
int main()
{
printf("  生产者消费者问题   3生产者 1消费者 4缓冲区\n");
printf(" -- by MoreWindows( http://blog.csdn.net/MoreWindows ) --\n\n");

InitializeCriticalSection(&g_cs);
//初始化信号量,一个记录有产品的缓冲区个数,另一个记录空缓冲区个数.
g_hSemaphoreBufferEmpty = CreateSemaphore(NULL, 4, 4, NULL);
g_hSemaphoreBufferFull  = CreateSemaphore(NULL, 0, 4, NULL);
g_i = 0;
g_j = 0;
memset(g_Buffer, 0, sizeof(g_Buffer));

const int THREADNUM = 4;
HANDLE hThread[THREADNUM];
//生产者线程 3个
hThread[0] = (HANDLE)_beginthreadex(NULL, 0, ProducerThreadFun, NULL, 0, NULL);
hThread[1] = (HANDLE)_beginthreadex(NULL, 0, ProducerThreadFun, NULL, 0, NULL);
hThread[2] = (HANDLE)_beginthreadex(NULL, 0, ProducerThreadFun, NULL, 0, NULL);
//消费者线程 1个
hThread[3] = (HANDLE)_beginthreadex(NULL, 0, ConsumerThreadFun, NULL, 0, NULL);

WaitForMultipleObjects(THREADNUM, hThread, TRUE, INFINITE);
for (int i = 0; i < THREADNUM; i++)
CloseHandle(hThread[i]);

//销毁信号量和关键段
CloseHandle(g_hSemaphoreBufferEmpty);
CloseHandle(g_hSemaphoreBufferFull);
DeleteCriticalSection(&g_cs);
return 0;
}


运行结果如下:



reference:/article/1358215.html
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: 
相关文章推荐