#include<Windows.h>
#include<string.h>
#include<iostream>
CRITICAL_SECTION Only_One; //用于控制只有一个生产者在临界区
//定义缓冲区大小
#define MAX_BUFFER_NUM 3
#define Cosumer_Size 1
//定义最大线程数
#define MAX_THREAD_NUM 4
#define IInitialCount 1
#define IMaximumCount 1
int Buffer_Critical[MAX_BUFFER_NUM]={0};
HANDLE h_mutex;
HANDLE empty_semephore;
//记录每个用户进程的需要产品数
int Cosumer_Thread_Num[Cosumer_Size]={0};
//创建信号量数组
HANDLE h_Semaphore[MAX_THREAD_NUM];
//临界区对象数组
CRITICAL_SECTION PC_Critical[MAX_BUFFER_NUM];
typedef struct ThreadInfo{
//进程号
int Thread_Num;
//进程类型
char Thread_Type;
//进程启动时间
int Thread_Time;
//生产者进程号
int Producer_Thread_Num[20];
}*Struct_Pointer;
DWORD WINAPI ThreadProc(LPVOID lpParam)
{
int q=(int)lpParam;
printf("%d号进程等待empty_semephore信号量,检查是否存在空闲区\n",q);
WaitForSingleObject(empty_semephore,INFINITE);
{
printf("%d号进程存在空闲区供写入\n",q);
printf("%d号进程等待互斥量h_mutex,检查是否有另一生产者在写\n",q);
WaitForSingleObject(h_mutex,INFINITE);
{
printf("%d号进程没有其他生产者在写入\n",q);
EnterCriticalSection(&Only_One);
printf("%d号进程进入临界区\n",q);
printf("%d 号线程运行中!!\n",q);
int i=0;
for(i=0;i<MAX_BUFFER_NUM ;i++ )
{
if(Buffer_Critical[i]==0)
{
printf("%d 号线程分配缓冲区成功!!\n",q);
break;
}
}
LeaveCriticalSection(&Only_One);
printf("%d 号线程退出临界区\n",q);
Buffer_Critical[i]=q;
printf("%d 号线程写入缓冲区成功!!\n",q);
//=CreateSemaphore(NULL,IInitialCount,IMaximumCount,NULL);
ReleaseSemaphore(h_Semaphore[q-1],1,NULL);
printf("%d 号线程信号量写入成功!!\n",q);
}
ReleaseMutex(h_mutex);
printf("%d 号线程互斥量释放成功\n",q);
}
ReleaseSemaphore(empty_semephore,1,NULL);
printf("%d 号线程信号量释放成功\n",q);
}
DWORD WINAPI ThreadProc_Cos(LPVOID lpParam)
{
int Count_Signal=0;
int num=((Struct_Pointer)lpParam)->Thread_Num;
int checkp=((Struct_Pointer)lpParam)->Producer_Thread_Num[0];
int p=((Struct_Pointer)lpParam)->Thread_Num;
if(Cosumer_Thread_Num[p-MAX_BUFFER_NUM-1]==0)
{
printf("%d号线程没有消费请求,结束线程\n",p);
return(0);
}
else
{
Count_Signal=Cosumer_Thread_Num[num-MAX_BUFFER_NUM-1];
//使用循环获取等待的信号量数
//for(int i=0; ; i++)
//{
//int temp_arry=((Struct_Pointer)lpParam)->Producer_Thread_Num[i];
//if(temp_arry==0)
//{
//break;
//}
//else
//{
//Count_Signal+=1;
//}
//}
//使用for循环等待所有进程完成
printf("%d号线程等待消费完成\n",p);
for(int i=0;i<Count_Signal;i++)
{
int temp_arry_Num=((Struct_Pointer)lpParam)->Producer_Thread_Num[i];
WaitForSingleObject(h_Semaphore[temp_arry_Num-1],INFINITE);
{
//如果该进程已经完成则测试是否在缓冲区
if(TryEnterCriticalSection(&PC_Critical[temp_arry_Num-1]))
{
printf("产品%d没有消费者在消费,可用!\n",temp_arry_Num);
}
else
{
printf("产品%d有消费者在消费,不可用!\n",temp_arry_Num);
}
EnterCriticalSection(&PC_Critical[temp_arry_Num-1]);
printf("%d号进程进入产品%d临界区\n",p,temp_arry_Num);
printf("%d号进程消费%d号产品\n",p,temp_arry_Num);
LeaveCriticalSection(&PC_Critical[temp_arry_Num-1]);
printf("%d号进程退出产品%d临界区\n",p,temp_arry_Num);
}
}
printf("%d号消费者消费完毕,结束线程\n",p);
}
}
{
// 进程结构数组
struct ThreadInfo Thread_Info[MAX_BUFFER_NUM+Cosumer_Size];
//初始化排序数组
int Sort_ThreadInfo[MAX_BUFFER_NUM+Cosumer_Size][2]={0} ;
//
//输入部分
//
//输入生产者线程
for(int i=0;i<MAX_BUFFER_NUM;i++)
{
scanf("%d %c %d",&Thread_Info[i].Thread_Num,&Thread_Info[i].Thread_Type,&Thread_Info[i].Thread_Time);
Sort_ThreadInfo[i][0]=Thread_Info[i].Thread_Num;
Sort_ThreadInfo[i][1]=Thread_Info[i].Thread_Time;
}
//结束输入流
//fflush(stdin);
getchar();
//输入消费者线程
for(int i=0;i<Cosumer_Size;i++)
{
int Count_Producer_Num=0;
char input[50];
//初始化字符串
memset(input,'\0',sizeof(input));
//初始化数组
memset(Thread_Info[i+Cosumer_Size].Producer_Thread_Num,0,sizeof(Thread_Info[i].Producer_Thread_Num));
scanf("%[^\n]",&input);
//结束输入流
fflush(stdin);
for(int j=0;j<sizeof(input);j++)
{
if(input[j]=='\n')
{
break;
}
if(j>4)
{
if(input[j]>='0'&&input[j]<='9')
{
Thread_Info[MAX_BUFFER_NUM+i].Producer_Thread_Num[Count_Producer_Num]=input[j]-'0';
Count_Producer_Num+=1;
Cosumer_Thread_Num[i]=Count_Producer_Num;
}
}
else if(j==0)
{
Thread_Info[MAX_BUFFER_NUM+i].Thread_Num=input[j]-'0';
Sort_ThreadInfo[MAX_BUFFER_NUM+i][0]=Thread_Info[MAX_BUFFER_NUM+i].Thread_Num;
}
else if(j==2)
{
Thread_Info[MAX_BUFFER_NUM+i].Thread_Type=input[j];
}
else if(j==4)
{
Thread_Info[MAX_BUFFER_NUM+i].Thread_Time=input[j]-'0';
Sort_ThreadInfo[MAX_BUFFER_NUM+i][1]=Thread_Info[MAX_BUFFER_NUM+i].Thread_Time;
}
}
}
//对线程时间进行排序 0号为进程号,1为时间
for(int i=0;i<MAX_BUFFER_NUM+Cosumer_Size;i++)
{
int Temp_sort=Sort_ThreadInfo[i][1];
int Temp_sort_0=Sort_ThreadInfo[i][0];
for(int j=i+1;j<MAX_BUFFER_NUM+Cosumer_Size;j++)
{
if(Temp_sort>=Sort_ThreadInfo[j][1])
{
Sort_ThreadInfo[i][0]=Sort_ThreadInfo[j][0];
Sort_ThreadInfo[i][1]=Sort_ThreadInfo[j][1];
Sort_ThreadInfo[j][0]=Temp_sort_0;
Sort_ThreadInfo[j][1]=Temp_sort;
Temp_sort_0=Sort_ThreadInfo[i][0];
Temp_sort=Sort_ThreadInfo[i][1];
}
}
}
//
//
//
//
//初始化部分
//
//创建互斥量h_mutex
//初始化产品是否已经生产的信号量数组
for(int i=0;i<MAX_THREAD_NUM;i++)
{
h_Semaphore[i]=CreateSemaphore(NULL,0,1,NULL);
}
//空缓冲区数目信号量
//临界区对象数组
for(int i=0;i<MAX_BUFFER_NUM;i++)
{
InitializeCriticalSection(&PC_Critical[i]);
}
//
//
//
//
//开始模拟
//
HANDLE Thread[MAX_BUFFER_NUM+Cosumer_Size];
int Count_Num=0;
//初始化临界区
InitializeCriticalSection(&Only_One);
while(1)
{
if(Thread_Info[(Sort_ThreadInfo[Count_Num][0])-1].Thread_Type=='p')
{
//为生产者创建进程 ,并传递进程号。
Thread[Count_Num]=CreateThread(NULL,0,ThreadProc,(LPVOID)(Thread_Info[(Sort_ThreadInfo[Count_Num][0])-1].Thread_Num),0,NULL);
Sleep(1);
Count_Num+=1;
}
else if(Count_Num<MAX_BUFFER_NUM+Cosumer_Size)
{
Thread[Count_Num]=CreateThread(NULL,0,ThreadProc_Cos,(LPVOID)&(Thread_Info[(Sort_ThreadInfo[Count_Num][0])-1]),0,NULL);
Sleep(1);
Count_Num+=1;
}
if(Count_Num==MAX_BUFFER_NUM+Cosumer_Size)
{
break;
}
}
Sleep(100000);
printf("end");
}