实验内容
实验内容三 利用线程信号量实现生产者和消费者之间的同步
生产者和消费者实例:
有一个仓库生产者负责生产产品,并放入仓库,消费者从仓库拿走产品,要求仓库每次只能入一人,仓库中最多存放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),当然执行一次就结束啦。。。。。。。。。。。。。
我当时就——
最后,捋一捋
- 目前调试水平还是太差了,科学调试、科学调试、科学调试,谁不想啊
- 最后其实没整明白为什么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
——————————————————————
僕らタイムフライヤー 時を駆け上がるクライマー
我们是时间的旅行者 时光阶梯上追逐着的攀缘者
時のかくれんぼ はぐれっこはもういやなんだ
我不愿在流逝的时光里捉迷藏 逃避自我
嬉しくて泣くのは 悲しくて笑うのは
你会喜极而泣 含泪微笑
君の心が 君を追い越したんだよ
都是因为你的心 追过了自己啊
————————————————