⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 yuobhsdg.cpp

📁 (1) 掌握基本的同步与互斥算法
💻 CPP
字号:
#include <windows.h> 
#include <conio.h> 
#include <wtypes.h> 
#include <winbase.h> 
#include <stdio.h> 
#include <stdlib.h>  
#define MAXTHREAD 10                                //最大线程数
#define PARA 10                                     //最大线程参数
#define MAXBUFFER 10                                   //最大缓冲区间数


struct Parament                                   //结构体定义
{ 
	int id;                                     //线程号
	char kind;                                  //线程类型
	int time;                                   //休眠时间
	int num[PARA];                              //消费的产品所对应的生产者线程号
};static struct Parament Thread_Info[MAXTHREAD]={0};

	int Buffer[MAXBUFFER]={0};
	HANDLE hMutex;                   //互斥量
	HANDLE thread[MAXTHREAD];        //线程
	HANDLE empty;                   
	CRITICAL_SECTION pcc[MAXBUFFER];   //临界区对象
	HANDLE hSemaphore[MAXTHREAD];   //信号量
	int need[MAXTHREAD];            //定义为空数组
	int x;

DWORD WINAPI pwork(LPVOID arg)                             //生产者生产流程(LPVOID定义无类型指针)
{ 
	int i;
	struct Parament *N =(struct Parament *)arg; 

	Sleep(1000*(N->time));
	printf("%d :申请缓冲区\n",N->id);
	WaitForSingleObject(empty,INFINITE);                   //使程序处于等待状态,直到信号量hHandle出现(即其值大于等于1)或超过规定的等待时间
	WaitForMultipleObjects(1,&hMutex,1,INFINITE);          //使多个线程处于等待状态,直到互斥量hHandle出现或超过规定的等待时间
	printf("%d :正在写入\n",N->id);
	for(i=0;i<MAXBUFFER;i++) 
	{ 
		if(Buffer[i]==0)
		{
			Buffer[i]=N->id;
			Sleep(1000);
			break;
		}
	} 
	printf("%d :生产完毕 产品在缓冲区%d\n",N->id,i+1);
	ReleaseMutex(hMutex);                                   //打开互斥锁,即互斥量+1,成功调用则返回0 
	ReleaseSemaphore(hSemaphore[N->id],1,NULL);             //对指定信号量加上一个指定大小的量,成功执行则返回非0值 
	ExitThread(0); 
	return TRUE; 
} 



DWORD WINAPI cwork(LPVOID arg)                               //消费者消费流程(LPVOID定义无类型指针)
{ 
	int i=0,j;
	struct Parament *N =(struct Parament *)arg; 

	Sleep(1000*(N->time));                                   //释放CPU控制权,挂起
	while(N->num[i]!=0)
	{
		printf("%d :请求消费产品%d\n",N->id,N->num[i]);
		WaitForSingleObject(hSemaphore[N->num[i]],INFINITE); //使程序处于等待状态,直到信号量hHandle出现(即其值大于等于1)或超过规定的等待时间
		for(j=0;j<MAXBUFFER;j++)
		{
			if(N->num[i]==Buffer[j])
			{
				break;
			}
		}
		printf("%d :消费在缓冲区%d的产品%d\n",N->id,j+1,N->num[i]);
		EnterCriticalSection(&pcc[N->num[i]]);                //等待指定临界区对象的所有权
		need[N->num[i]]--;
		if(!need[N->num[i]])
		{
			Buffer[j]=0;
			ReleaseSemaphore(empty,1,NULL);                  //对指定信号量加上一个指定大小的量,成功执行返回非0值
			printf("%d :释放产品所占缓冲区%d.\n",N->id,j+1);
		}
		Sleep(1000);                                         //挂起
		LeaveCriticalSection(&pcc[N->num[i]]);               //释放指定临界区对象的所有权
		printf("%d :消费完毕\n",N->id);
		i++;
	}
	ExitThread(0); 
	return TRUE; 
}


 
DWORD WINAPI stop(LPVOID arg)                              //终止线程
{ 
	ExitThread(0); 
	return TRUE; 
}


 
int inputPARA(struct Parament *Thread_Info)                  //输入测试用例文件信息并记录
{
		int a,b=2;
		printf("线程类型(P-生产者 C-消费者):");                    //定义线程类型,是生产者还是消费者
		for(;b!=0;b--)
		{
		scanf("%c",&(Thread_Info->kind));
		}
		printf("休眠时间: ");                            //线程在生产前的和消费前的休眠时间
		scanf("%d",&(Thread_Info->time));
		switch(Thread_Info->kind)
		{
		case'p': Thread_Info->kind='P';
		case'P': a=1;break;
		case'c': Thread_Info->kind='C';
		case'C': a=0;break;
		default: return 1 ;
		}
		if(a==0)
		{
			printf("输入消费产品对应的生产者线程号。按0结束.\n");
			for(a=0;a<PARA;a++)
			{
				printf("生产者线程号[%d]= ",a+1);
				scanf("%d",&(Thread_Info->num[a]));
				if(Thread_Info->num[a]<1)
				{
					Thread_Info->num[a]=0;
					break;
				}
				need[Thread_Info->num[a]]++;
			}
		}
	return 0;
}


int main(int argc, char *argv[]) 
{ 
	
	int k;
	int flag=0,n=0,chack;
	printf("要创建线程吗?按1继续");
	scanf("%d",&chack);
	if(chack==1)
	{
		while (!flag)
		{
			system("cls");                           //清屏
			printf("正在创建的线程是线程 %d\n开始输入:\n",n+1);
			Thread_Info[n].id=n+1;
			chack=inputPARA(&Thread_Info[n]);
			for(int a=0;a<PARA;a++)
			{
				if(Thread_Info[n].num[a]==0)
					break;

			}
			printf("\n创建完毕?[1.是 0.不]");
			scanf("%d",&flag);
			n++;
			n=n-chack;
		}
		
	}
	system("cls");                                      //清屏
	hMutex = CreateMutex(NULL,FALSE,NULL);              //创建一个互斥量对象 
	empty = CreateSemaphore(NULL,MAXBUFFER,MAXBUFFER+1,NULL); //创建一个信号量对象 
	for(k=0;k<MAXTHREAD;k++)
	{
		hSemaphore[k] = CreateSemaphore(NULL,0,MAXBUFFER+1,NULL);//创建一个信号量
	}
	for(k=0;k<MAXBUFFER;k++)
	{
		InitializeCriticalSection(&pcc[k]);           //初始化临界区对象
	}
	for(k=0;k<MAXTHREAD;k++)
	{
		if(Thread_Info[k].id==0)
			break;
		switch(Thread_Info[k].kind)
		{
		case 'P':thread[k] = CreateThread(NULL,0,pwork,&Thread_Info[k],0,NULL); break;   //创建一个生产者进程
		case 'C':thread[k] = CreateThread(NULL,0,cwork,&Thread_Info[k],0,NULL); break;   //创建一个消费者进程
		default: printf("错误输入!");return 0;
		}
		printf("%d	%c	%d	",Thread_Info[k].id,Thread_Info[k].kind,Thread_Info[k].time);
		for(int a=0;a<PARA;a++)
		{
			if(Thread_Info[k].num[a]==0)
				break;
			printf("%d	",Thread_Info[k].num[a]);
		}
		printf("\n");
	}
	while(k!=MAXTHREAD)
	{
		thread[k] = CreateThread(NULL,0,stop,&Thread_Info[k],0,NULL);                     //挂起
		k++;
	}
	WaitForMultipleObjects(MAXTHREAD,thread,TRUE,INFINITE);          //使多个线程处于等待状态,直到互斥量hHandle出现或超过规定的等待时间
	printf("所有线程结束!!\n"); 
	return 0; 
}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -