利用线程信号量实现生产者和消费者之间的同步(linux环境,C语言)

实验内容

实验内容三 利用线程信号量实现生产者和消费者之间的同步

生产者和消费者实例:
有一个仓库生产者负责生产产品,并放入仓库,消费者从仓库拿走产品,要求仓库每次只能入一人,仓库中最多存放10个产品,仓库满时不能再放入产品,仓库空时不能再从中取出产品,生产消费速度不同
参考思路:
(1)生产和消费各一个线程,仓库为互斥,假设容量为10,库存为3;
(2)假设生产速度比消费速度快,信号量的值等于剩余产品;

在以下程序中,已经给出主函数,要求实现void *produce(void *arg)()和void *cost(void *arg)()两个函数并对整个程序进行调试运行。
在每一个函数中,如果工作条件满足情况下,先等待某个信号量,再进行线程各自的操作(产品数的变化,显示当前工作的产品数),再释放另一个信号量。

#include<stdio.h>
#include<sys/stat.h>
#include<fcntl.h>
#include<semaphore.h>
int total=10;//总量
int last=7;//剩余量
sem_t sem_p;
sem_t sem_c;
void *produce(void *arg)
{	
}
void *cost(void *arg)
{	
}
int main()
{
	pthread_t pth_p,pth_c;
	sem_init(&sem_p,0,total-last);
	sem_init(&sem_c,0,last);
	printf("init_last=%d\n",last);
	pthread_create(&pth_p,NULL,produce,NULL);
	pthread_create(&pth_c,NULL,cost,NULL);
	sem_destroy(&sem_p)sem_destroy(&sem_c)while(1);
	return 0;
}

日常哔哔

诶,我就菜的离谱。查了一下信号量sem_t的有关函数,程序一下就敲完了,整不明白不知道为什么我的生产者、消费者线程各执行一次后,就卡着了。
在这里插入图片描述
我当时就认为,怎么死锁了???

接着把本来用的互斥锁换成了互斥信号量,嗯,还是老样子。

瞎调试了一个多小时,意外的发现了生产者、消费者线程里,没给死循环while(1),当然执行一次就结束啦。。。。。。。。。。。。。

我当时就——
在这里插入图片描述在这里插入图片描述在这里插入图片描述
最后,捋一捋

  1. 目前调试水平还是太差了,科学调试、科学调试、科学调试,谁不想啊
  2. 最后其实没整明白为什么sem_t 类型的信号量输出会出错,我最后是通过输出全局变量 last 来规避掉这个问题的。哎呀,以后再说啦~

代码(linux环境,C语言)

#include<stdio.h>
#include<sys/stat.h>
#include<fcntl.h>
#include<semaphore.h>
#include <pthread.h>
#include <unistd.h>
int total=10;	//仓库总容量
int last=7;		//初始剩余量
int mu = 1;	    //互斥信号量 

//创建信号量
sem_t sem_p;	 
sem_t sem_c;
sem_t mutex; 

//生产者线程 
void *produce(void *arg)
{	
	while (1)
	{	
		//阻塞当前线程直到信号量sem的值大于0,解除阻塞后将sem的值减1
		sem_wait(&sem_p);	//等待信号量 p  
		sem_wait(&mutex);
	
		sem_post(&sem_c);	//增加信号量的值 
		last ++ ;
		printf("当前执行线程:%s 仓库库存为 %d 件产品\n\n", (char*)arg, last);
	
		sem_post(&mutex);
		sleep(1);	//生产速度设置为 1s一次 
	}
}

//消费者线程 
void *cost(void *arg)
{	
	while (1)
	{
		//阻塞当前线程直到信号量sem的值大于0,解除阻塞后将sem的值减1
		sem_wait(&sem_c);	//等待信号量 c 
		sem_wait(&mutex);
	
		sem_post(&sem_p);	//增加信号量的值 
		last -- ;
		printf("当前执行线程:%s 仓库库存为 %d 件产品\n\n", (char*)arg, last);
	
		sem_post(&mutex);
		sleep(2);	//消费速度设置为 2s一次 
	}
}

int main()
{ 
	//定义2线程 
	pthread_t pth_p,pth_c;
	
	//参数0 表示此信号量只能为当前进程的所有线程共享 
	//初始化信号量sem_p,表示生产者当前可执行3次 
	sem_init(&sem_p,0,total-last);
		 
	//初始化信号量sem_c, 表示消费者当前可执行7次
	sem_init(&sem_c,0,last);
	
	//互斥信号量 初始值为 1 
	sem_init(&mutex,0, mu);
	
	printf("mutex = %d\n", mu);
	printf("init_last=%d\n",last);
	
	//创建生产者、消费者线程 
	pthread_create(&pth_p,NULL,produce,"生产者###");
	pthread_create(&pth_c,NULL,cost,"###消费者");
	
	//销毁信号量 
	sem_destroy(&sem_p);
	sem_destroy(&sem_c);
	sem_destroy(&mutex);
	
	while(1);
	
	return 0;
}

END
——————————————————————
僕らタイムフライヤー 時を駆け上がるクライマー
我们是时间的旅行者 时光阶梯上追逐着的攀缘者
時のかくれんぼ はぐれっこはもういやなんだ
我不愿在流逝的时光里捉迷藏 逃避自我
嬉しくて泣くのは 悲しくて笑うのは
你会喜极而泣 含泪微笑
君の心が 君を追い越したんだよ
都是因为你的心 追过了自己啊
————————————————

  • 7
    点赞
  • 19
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值