生产者消费者问题c语言实现

时间:2023-03-10 00:42:47
生产者消费者问题c语言实现
 #include <stdio.h>
#include <process.h>
#include <Windows.h>
//信号量与关键段
CRITICAL_SECTION g_cs;
HANDLE Empty,Full; const int BUFFER_SIZE=;//10个缓冲池
const int numofp=;//生产者线程数
const int numofc=;//消费者线程数
const int numofpr=;//要生产的产品数
int buffer[BUFFER_SIZE];
int pf=,pe=;
int count=;
int count_c=;
int mp=; //生产者
unsigned int __stdcall Producer(PVOID p){ while(true){
//等待有空的缓冲区出现
WaitForSingleObject(Empty, INFINITE);
//互斥的访问缓冲区
EnterCriticalSection(&g_cs);
if(count>numofpr){
LeaveCriticalSection(&g_cs);
ReleaseSemaphore(Full,,NULL);
break;
}
buffer[pe]=++mp;
//printf("%d,",*((int *)p));
printf("编号为%d的生产者从第%d个空缓冲池中写入数据%d\n",*((int *)p),pe,buffer[pe]);
pe=(pe+)%BUFFER_SIZE;
count++;
LeaveCriticalSection(&g_cs);
//通知消费者有新数据了
ReleaseSemaphore(Full,,NULL);
}
return ;
}
//消费者
unsigned int __stdcall Consumer(PVOID p){ while(true){
WaitForSingleObject(Full,INFINITE);
EnterCriticalSection(&g_cs);
if(count_c>numofpr){
LeaveCriticalSection(&g_cs);
ReleaseSemaphore(Empty,,NULL);
break;
}
//printf("%d,",*((int *)p));
printf(" 编号为%d的消费者从第%d个FULL缓冲区中取出数据%d\n",*((int *)p),pf,buffer[pf]);
pf=(pf+)%BUFFER_SIZE;
count_c++;
LeaveCriticalSection(&g_cs);
ReleaseSemaphore(Empty,,NULL);
}
return ;
} int main(){
printf(" 生产者消费者问题:%d生产者-%d消费者-%d缓冲区-%d个产品\n\n",numofp,numofc,BUFFER_SIZE,numofpr);
InitializeCriticalSection(&g_cs);//初始化一个临界区对象
//初始化信号量,一个记录有产品的缓冲区个数,另一个记录空缓冲区个数.
Empty=CreateSemaphore(NULL,,,NULL);
Full=CreateSemaphore(NULL,,,NULL);
const int THREADNUM=numofc+numofp;//线程数
HANDLE hThread[THREADNUM];
//生产者线程
int a=,b=,c=,d=;
hThread[]=(HANDLE)_beginthreadex(
NULL,//安全属性,NULL为默认安全属性
,//指定线程堆栈的大小,一般为0
Producer,//指定线程函数的地址
&a,//传递给线程的参数的指针
,//线程初始状态,0:立即运行
NULL);//用于记录线程ID的地址 hThread[]=(HANDLE)_beginthreadex(NULL,,Producer,&b,,NULL); hThread[]=(HANDLE)_beginthreadex(NULL,,Consumer,&c,,NULL); hThread[]=(HANDLE)_beginthreadex(NULL,,Consumer,&d,,NULL);
WaitForMultipleObjects(THREADNUM, hThread, TRUE, INFINITE);
for (int i = ; i < THREADNUM; i++)
CloseHandle(hThread[i]); //销毁信号量和关键段
CloseHandle(Empty);
CloseHandle(Full);
DeleteCriticalSection(&g_cs);
system("pause"); return ;
}