生产者与消费者问题(C语言 超详细全)小白可入

#include<stdio.h>
#include<pthread.h>//pthread_create()函数的头文件
#include<windows.h>//sleep的头文件 
#define N 10
#define true 1 
#define sleepTime 1000//1000就是1S
#define producerNum 4
#define consumerNum 3 
typedef int semaphore;
typedef int item;
item buffer[N]={0};//缓冲池的情况 
int in=0;//生产者的指针
int out=0;//消费者的指针
semaphore mutex=1;//互斥性信号量 
semaphore empty=N;//空着的缓冲区数 
semaphore full=0;//有东西的缓冲区数
void *producer(void *a)
{
	while(true)
	{
		while(empty<=0)
		{
			printf("缓冲区已满!\n");
		}
		empty--;//执行P操作
		
		while(mutex<=0);//判断是否能进入缓冲区(mutex=1可入)
		mutex--;//进行P操作
		
		buffer[in]=1;//生产完缓冲区设置为1
		in=(in+1)%N;//是环形存储为了防止出现假溢出的现象
		
		mutex++;//执行V操作 
		full++;//上下两步可调整先后
		Sleep(sleepTime);
		//当我们设置sleep时,等于告诉cpu,当前的线程不再运行,持有当前对象的锁。
		//那么这个时候cpu就会切换到另外的线程了。这种操作有些时候是非常好的。
	}
}
void *consumer(void*b)
{
	while(true)
	{
		while(full<=0)
		{
			printf("缓冲区为空!\n"); 
		}
		full--;//执行P操作 
		
		while(mutex<=0);
		mutex--;
		
		int nextc=buffer[out];
		buffer[out]=0;//消费完将缓冲区设置为0
		out=(out+1)%N;
		
		mutex++;
		empty++;
		
		printf("消费一个产品ID%d,缓冲区位置为%d\n", nextc,out);
		Sleep(sleepTime);
	}
 } 
int main()
{
	//创建进程池,就是所有进程都能放进去的一个线程组 
	pthread_t threadPool[producerNum+consumerNum];
	
	int i;
	for(i=0;i<producerNum;i++)
	{
		pthread_t temp;
		//pthread_t是一个表示线程的数据类型
		//pthread_create是用来创建线程的 
		if(pthread_create(&temp,NULL,producer,NULL)==-1)
		{
			//pthread_create的第一个参数是指向线程标识符的指针
			//第二个参数是用来设置线程的属性(一般不用设置所以一般为NULL) 
			//第三个参数是线程运行函数的起始地址(就是新建线程需要执行的函数,该函数的参数最多有 1 个(可以省略不写)) 
			//第四个参数是运行函数的参数 
			printf("ERROR, fail to create producer%d\n",i);
			exit(1);
		}
		threadPool[i]=temp;
	 }//创建生产者线程放入线程池
	 for(i=0;i<consumerNum;i++)
	 {
	 	pthread_t temp;
	 	if(pthread_create(&temp,NULL,consumer,NULL)==-1)
	 	{
	 		printf("ERROR, fail to create consumer%d\n",i);
	 		exit(1);	
		}
		threadPool[i+producerNum]=temp; 
	 }//创建消费者线程放入线程池
	 void *result;
	 for(i=0;i<producerNum+consumerNum;i++)
	 {
	 	if(pthread_join(threadPool[i],&result)==-1)
	 	{
	 		printf("fail to recollect\n");
	 		exit(1);
		 }
	 }//运行线程池
	return 0;
}

  • 20
    点赞
  • 173
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
以下是一个简单的生产者消费者问题的C语言实现: ```c #include <stdio.h> #include <stdlib.h> #include <pthread.h> #include <semaphore.h> #define BUFFER_SIZE 5 // 缓冲区大小 int buffer[BUFFER_SIZE]; // 缓冲区 int in = 0; // 生产者将产品放缓冲区的位置 int out = 0; // 消费者从缓冲区取走产品的位置 sem_t empty; // 空缓冲区信号量 sem_t full; // 满缓冲区信号量 pthread_mutex_t mutex; // 互斥锁 void *producer(void *arg) { // 生产者线程 for (int i = 0; i < 10; i++) { // 生产10个产品 sem_wait(&empty); // 等待空缓冲区 pthread_mutex_lock(&mutex); // 加锁 buffer[in] = i; // 将产品放缓冲区 printf("Producer produces item %d at position %d.\n", i, in); in = (in + 1) % BUFFER_SIZE; // 更新in指针 pthread_mutex_unlock(&mutex); // 解锁 sem_post(&full); // 发出满缓冲区信号 sleep(1); // 生产一个产品需要1秒钟 } pthread_exit(NULL); } void *consumer(void *arg) { // 消费者线程 int item; for (int i = 0; i < 10; i++) { // 消费10个产品 sem_wait(&full); // 等待满缓冲区 pthread_mutex_lock(&mutex); // 加锁 item = buffer[out]; // 从缓冲区取走一个产品 printf("Consumer consumes item %d from position %d.\n", item, out); out = (out + 1) % BUFFER_SIZE; // 更新out指针 pthread_mutex_unlock(&mutex); // 解锁 sem_post(&empty); // 发出空缓冲区信号 sleep(2); // 消费一个产品需要2秒钟 } pthread_exit(NULL); } int main() { pthread_t producer_thread, consumer_thread; sem_init(&empty, 0, BUFFER_SIZE); // 初始化空缓冲区信号量为BUFFER_SIZE sem_init(&full, 0, 0); // 初始化满缓冲区信号量为0 pthread_mutex_init(&mutex, NULL); // 初始化互斥锁 pthread_create(&producer_thread, NULL, producer, NULL); // 创建生产者线程 pthread_create(&consumer_thread, NULL, consumer, NULL); // 创建消费者线程 pthread_join(producer_thread, NULL); // 等待生产者线程结束 pthread_join(consumer_thread, NULL); // 等待消费者线程结束 sem_destroy(&empty); // 销毁空缓冲区信号量 sem_destroy(&full); // 销毁满缓冲区信号量 pthread_mutex_destroy(&mutex); // 销毁互斥锁 return 0; } ``` 在这个程序中,我们使用了一个长度为5的缓冲区来存放产品。生产者消费者通过互斥锁来保证对缓冲区的访问是互斥的,通过信号量来保证生产者消费者之间的同步。 在生产者线程中,每当生产一个产品,就需要先等待空缓冲区信号量,表示缓冲区中有空位置可以放置产品,然后再获得互斥锁,将产品放缓冲区,更新in指针,释放互斥锁,发出满缓冲区信号量,表示缓冲区中已经有产品了。生产一个产品需要1秒钟。 在消费者线程中,每当消费一个产品,就需要先等待满缓冲区信号量,表示缓冲区中已经有产品可以取走,然后再获得互斥锁,从缓冲区中取走一个产品,更新out指针,释放互斥锁,发出空缓冲区信号量,表示缓冲区中又有空位置了。消费一个产品需要2秒钟。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值