C语言 生产者消费者问题

目录

  • 生产者消费者问题
  • 算法设计
  • 实现
  • 源程序
  • 测试日志
  • 总结


生产者消费者问题

C语言 生产者消费者问题_第1张图片

算法设计

C语言 生产者消费者问题_第2张图片

实现

1.编写所需头文件

#include
#include

2.定义全局变量

#define productor 2  //生产者数目 为2
#define consumers 3  //消费者数目 为3
#define buffers 10    //缓冲区数目 为10
int nextp1 = 1000;   //生产者1生产数据
int nextp2=2000;	    //生产者2生产数据
int buf[buffers] = {
      0 };	//缓冲区数组
FILE *fpWrite=fopen("D:\\4.txt","w");  //日志文件写入位置

3.编写相关信号量

empty = CreateSemaphore(NULL, buffers, buffers, NULL);   //信号量,缓冲区空位数量
full = CreateSemaphore(NULL, 0, buffers, NULL);          //信号量,缓冲区数据的个数
huchu = CreateSemaphore(NULL, 1, 1, NULL);           //信号量,缓冲区互斥使用

第二个参数为初始量,第三个参数为最大值
4.编写创建线程函数

hThread[i] = CreateThread(NULL, 0, producer, (LPVOID*)&pID[i], 0, NULL);  //创建生产者线程
hThread[i + productor] = CreateThread(NULL, 0, consumer, (LPVOID*)&cID[i], 0, NULL);  //创建消费者进程

5.编写生产者,消费者相关函数
生产者关键代码:

P(empty);
P(huchu);
if(id==1)
		{
     
		buf[in] = nextp1;
		fprintf(fpWrite,"生产者%d 将数据%d 放入缓冲区%d\n", id, nextp1, in);
		nextp1++;
		}
else
		{
     
			buf[in]=nextp2;
			fprintf(fpWrite,"生产者%d 将数据%d 放入缓冲区%d\n", id, nextp2, in);
            nextp2++;
		}   //通过ID判断是哪一个生产者,生产不同数据
V(huchu);
V(full);

消费者关键代码:

P(full);
P(huchu);

fprintf(fpWrite,"\t\t\t\t\t\t消费者%d 将数据%d 取出缓冲区%d\n", id, num, out);
out = (out + 1) % buffers;
V(huchu);
V(empty);

6.编写线程关闭,IO关闭

WaitForMultipleObjects(num_of_thread, hThread, TRUE, INFINITE);
printf("写入完成\n");

源程序

#include
#include
#define productor 2
#define consumers 3
#define buffers 10
#define P(S)  WaitForSingleObject(S,INFINITE) 
#define V(S)  ReleaseSemaphore(S,1,NULL)	  

int nextp1 = 1000;
int nextp2=2000;						
int in = 0, out = 0;				
int buf[buffers] = {
      0 };	
FILE *fpWrite=fopen("D:\\4.txt","w");  

HANDLE empty, full;			
HANDLE huchu;				
									
DWORD WINAPI producer(LPVOID pM)
{
     
	while (true)
	{
     
		int id = *((int*)(pM));	
		Sleep(100);
		P(empty);
		P(huchu);

		Sleep(100);
		if(id==1)
		{
     
		buf[in] = nextp1;
		fprintf(fpWrite,"生产者%d 将数据%d 放入缓冲区%d\n", id, nextp1, in);
		nextp1++;
		}
		else
		{
     
			buf[in]=nextp2;
			fprintf(fpWrite,"生产者%d 将数据%d 放入缓冲区%d\n", id, nextp2, in);
            nextp2++;
		}
				
		in = (in + 1) % buffers;

		V(huchu);
		V(full);
		if (nextp1 > 1200||nextp2>2200)
		{
     
		    fclose(fpWrite);
			break;
		}
	}
	return 0;
}
DWORD WINAPI consumer(LPVOID pM)

{
     
	while (true)
	{
     
		int id = *((int*)(pM));	
		Sleep(100);
		P(full);
		P(huchu);

		Sleep(100);
		int num = buf[out];
		buf[out] = 0;
		fprintf(fpWrite,"\t\t\t\t\t\t消费者%d 将数据%d 取出缓冲区%d\n", id, num, out);
		out = (out + 1) % buffers;

		V(huchu);
		V(empty);
		
		if (nextp1 > 1200||nextp2>2200)
		{
     
			fclose(fpWrite);
			break;
		}
	}
	return 0;
}
int main()
{
     
	fprintf(fpWrite,"\t\t\t生产者消费者问题:%d生产者 %d消费者 %d缓冲区\n\n", productor, consumers, buffers);
	empty = CreateSemaphore(NULL, buffers, buffers, NULL);
	full = CreateSemaphore(NULL, 0, buffers, NULL);
	huchu = CreateSemaphore(NULL, 1, 1, NULL);

	const int num_of_thread = consumers + productor;
	HANDLE hThread[num_of_thread];

	int pID[2];
	for (int i = 0; i < productor; i++)
	{
     
		pID[i]= i + 1;
		hThread[i] = CreateThread(NULL, 0, producer, (LPVOID*)&pID[i], 0, NULL);
	}
	int cID[2];
	for (int i = 0; i < consumers; i++)
	{
     
		cID[i] = i + 1;
		hThread[i + productor] = CreateThread(NULL, 0, consumer, (LPVOID*)&cID[i], 0, NULL);
	}
	WaitForMultipleObjects(num_of_thread, hThread, TRUE, INFINITE);
	printf("写入完成\n");
	getchar();
	return 0;
}

测试日志

C语言 生产者消费者问题_第3张图片


总结

本文介绍并实现了生产者消费者经典进程同步问题。
有任何问题都可以在评论区和我交流~~

你可能感兴趣的:(操作系统,多线程,算法,操作系统)