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

算法设计

实现
1.编写所需头文件
#include<stdio.h>
#include<Windows.h>
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<stdio.h>
#include<Windows.h>
#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;
}
测试日志

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


















