简单生产者消费者模型C语言代码

 

多线程测试数据与占用情况

 



// 参考自 https://zhuanlan.zhihu.com/p/693482704
#include <stdio.h>
#include <pthread.h>
#include <stdlib.h>

typedef struct message {
	int a;
	int user;
	int front;			// 排队头头
	int rear;			// 排队尾巴
	int lenth;			// 排队长度
	int* have;			// 一个数组存数据
} message;


void* sender(void* msg) {
	message* m = (message*)msg;
	// 在纸上写代码,发现需要预检测

	// 一直生产
	while (1111) {


		int k = m->front;
		// 发现从 -1 开始,等于时,是有数据
		// 于是注释掉代码,从 0 开始

		// 又发现会不增长,于是又解除注释,此时 front 从 0开始了,此时 -1
		// 又只有 999 又禁用
		// 又禁用
//		k++;
//		k = k % m->lenth;

		// 等有没有空数据,如果没有空位置就不用宣布占用座位了
		// front = -1 追加数据
		// rear 是有,front 是空
//		while (k == m->rear) {
//		while (m->have[k] != 999) {
		// 循环后+1 如果有,就不使用
		while (m->have[k] == 999) {
			_sleep(10);
		}

		// 发现有空位置,宣布占用座位
		while (m->a == 1) {
			_sleep(10);
		}
		// 占座
		m->a = 1;

		// 写入数据
		m->have[k] = 999;
		printf("一键占用\n");
		printf("已经生产位置 : %d\n", m->front);
		// 记录,预检测,把影响扩大到数据,后续消费者检测可在新数据产生后检测到
		m->front++;
		m->front = m->front % m->lenth;
		// 结束占用
		m->a = 0;

		// 生产速度随便整一个
		_sleep(300);
	}
}



void* receiver(void* msg) {
	message* m = (message*)msg;
	// 在纸上写代码,发现需要预检测

	// 一直生产
	// 一直消费
	while (1111) {

//		int k = m->front;
		// 探测摸索 假定 rear 从-1开始,所以先加一
		int k = m->rear;

		// fornt从 0 开始后 ,raer 从 0 开始
		// 解除禁用,rear 所在是空,fornt所在是有
		// 然后禁用
		// rear是有,front是有
//		k++;
//		k = k % m->lenth;
		// 等有没有空数据,如果没有空位置就不用宣布占用座位了
		// 改0 1 0 -1 等于时,front是没有数据的
		// 原来是front+1,fornt%lenth 写起来麻烦而已
		// 发现相等时停止
		// rear 是有, front 是空
//		while (k == m->front) {
//		while (m->have[k] != -1) {
		// +1 循环有空,就不使用
		while (m->have[k] == -1) {
			_sleep(10);
		}

		// 发现有空位置,宣布占用座位
		while (m->a == 1) {
			_sleep(10);
		}
		// 占座
		m->a = 1;

		// 写入数据
//		m->have[k] = 999;
		m->have[k] = -1;
		printf("消费者 一键使用用\n");
		printf("已经占用位置 %d\n", m->rear);
		// 记录,预检测,把影响扩大到数据,后续消费者检测可在新数据产生后检测到
//		m->front++;
		m->rear++;
		m->rear = m->rear % m->lenth;
		// 结束占用
		m->a = 0;

		// 生产速度随便整一个
		// 消费速度随便整一个
//		_sleep(300);
		_sleep(200);
	}
}


int main() {


	message* msg = new message;

	msg->lenth = 10;
	msg->a = 0;
	msg->user = -1;
//	msg->front = -1;
//	msg->front = 0;
//	msg->front = 1;
	msg->front = 0;

	// 先跑起来,看看,然后再想想0,-1的事
//	msg->rear = 0;
//	msg->rear = -1;
	msg->rear = 0;
	msg->have = new int[10];
	for (int n = 0; n < 10; n++) {
		msg->have[n] = 0;
	}

	// 生产消费线程
	pthread_t send;
	pthread_t receive;

	pthread_create(&send, NULL, sender, (void*)msg);
	pthread_create(&receive, NULL, receiver, (void*)msg);


	// 打印数据看队列
	while (1) {

		while (msg->a == 1) {
			_sleep(100);
		}

		msg->a = 1;

		// 打印数据
		printf("商品库存情况:");
		for (int n = 0; n < 10; n++) {
			printf("%d ", msg->have[n]);
		}
		printf("\n");

		msg->a = 0;

//		_sleep(100);
		_sleep(300);
	}

}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值