面包师问题--linux实现

描述

面包师有很多面包和蛋糕,由 n 个销售人员销售。每个顾客进店后先取一个号,并且等着叫号。当一个销售人员空闲下来,就叫下一个号。请分别编写销售人员和顾客进程的程序。

算法

面包师问题
semaphore mutex_s =1	//店员叫号互斥
semaphore mutex_c =1	//顾客取号互斥
semaphore sala = n		//店员人数
semaphore customer =0	//顾客数
int count_c =0	//顾客取号数
int count_s =0 	//店员叫号数
void customer()
{
	P(mutex_c)	//申请取号
	count_c++;	//取号
	V(mutex_c)	//释放取号资源
	V(customer)	
	P(sala)		//申请店员
	购买...
}
void salaer()
{
	P(customer)	//等待顾客
	P(mutex_s)	//申请叫号
	count_s++;	//叫号号码
	V(mutex_s)	//释放叫号资源
	服务...	
	V(sala)		//释放店员
}


实现

#include <pthread.h>
#include <stdio.h>
#include <semaphore.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <sys/syscall.h>
#include <signal.h>
//库文件
#define CUSTOMER 10
#define SALA 4
//预定义 售货员和总接纳顾客的人数
static int running = 1;
static int num=0;
struct lamport{
pthread_mutex_t mutex_s; //互斥锁 顾客取号互斥
pthread_mutex_t mutex_c; //互斥锁 店员叫号互斥
sem_t sala; //店员信号量
sem_t customer; //顾客信号量
int count_s; //顾客与店员的 取/叫 号码
int count_c;
}lamp;
///init//
/*********************************************************
* 功能描述:初始化
* 输入参数:结构体 lamport
* 输出参数: 无

* 返回值: 无
* 其它说明:
************************************************************/
void init(struct lamport *p){
pthread_mutex_init(&p->mutex_c,NULL); //对各个变量及信号量
pthread_mutex_init(&p->mutex_s,NULL); //互斥锁等进行初始化
sem_init(&p->sala,0,SALA);
sem_init(&p->customer,0,0);
p->count_s = 0;
p->count_c = 0;
} 
10
///finish//
/*********************************************************
* 功能描述: 各信号量及互斥量等的清理和重置
* 输入参数: 结构体 lamport
* 输出参数: 无

* 返回值: 无
* 其它说明:
************************************************************/
void finish(struct lamport *p){
pthread_mutex_destroy(&p->mutex_c); //对各个变量及信号量
pthread_mutex_destroy(&p->mutex_s); //互斥锁等进行销毁
sem_destroy(&p->sala);
sem_destroy(&p->customer);
p->count_s = 0;
p->count_c = 0;
}
/*********************************************************
* 功能描述:顾客取号申请售货员
* 输入参数:结构体 lamport
* 输出参数: 无

* 返回值: 无
* 其它说明:
************************************************************/
void take(struct lamport *p, int thread)
{
printf("*****************************************\n");
printf("%d customer come...\n",thread); //顾客到来
pthread_mutex_lock(&p->mutex_c);
printf("%d customer take the number...\n",thread);
p->count_c++; //顾客取得号码
pthread_mutex_unlock(&p->mutex_c);
printf("%d customer apply...\n",thread); //顾客申请售货员服务
sem_post(&p->customer);
sem_wait(&p->sala);
printf("%d customer apply success ...\n",thread); //申请成功
printf("*****************************************\n");
sleep(1);
}
/*********************************************************
* 功能描述:售货员申请顾客叫号
11
* 输入参数:结构体 lamport
* 输出参数: 无

* 返回值: 无
* 其它说明:
************************************************************/
void call(struct lamport *p, int thread){
while(running){
printf("-----------------------------------------\n");
printf("the %d sala wait a customer\n",thread); //售货员等待顾客到来
sem_wait(&p->customer);
pthread_mutex_lock(&p->mutex_s); //顾客到来 申请为顾客服务
printf("sala %d will serve for customers\n",thread);
p->count_s++; //叫号
pthread_mutex_unlock(&p->mutex_s); //释放叫号资源
sleep(1);
num++;
sem_post(&p->sala);
printf("the %d sala server finish,free now \n",thread);
if(num>=CUSTOMER-3){ //所有顾客服务完毕 结束线程
running=-1;
printf(">>>>>>>>>%d exit>>>>>>>>>>\n",thread);
pthread_exit((void*)1);
}
printf("-----------------------------------------\n");}
}
///sala&customer/
/*********************************************************
* 功能描述:售货员和顾客
* 输入参数: NULL
* 输出参数: 无

* 返回值: 无
* 其它说明: 创建的线程由此跳转初始化自己的栈空间进行处理各
自的功能
************************************************************/
void *t_salar(void * arg){
long thread = (long)arg;
 call(&lamp,thread);
pthread_exit((void*)1);
12
}
void *t_customer(void *arg){
long thread = (long)arg;
 take(&lamp,thread);
pthread_exit((void*)1);
}
///main
/*********************************************************
* 功能描述:主函数,负责初始化和创建各个线程以及线程的连接等
* 输入参数: 无
* 输出参数: 无

* 返回值: 无
* 其它说明:
************************************************************/
int main(){
pthread_t custid[CUSTOMER];
pthread_t salatid[SALA];
int err;
init(&lamp);
for (int i = 0; i < SALA; i++) { ///分别为每个售货员创建线程
 err = pthread_create(&salatid[i], NULL, &t_salar, (void*)((long)i));
 if(err!=0){
printf("create saler thread %d erro \n",i);
return; //创建失败结束进程
}
 }
printf("All the salesmen are in position... \n");//创建完成 售货员就位
printf("====================================\n");
 for (int i = 0; i < CUSTOMER; ++i) {
 sleep(1); //每过一秒钟来到一位顾客
 err = pthread_create(&custid[i], NULL, &t_customer,
(void*)((long)i));
 if(err!=0){
printf("create customer thread %d erro \n",i);
return; //创建失败结束进程
}
13
 }
 for (int i = 0; i < SALA; i++) {
 pthread_join(salatid[i], NULL);
 }
for (int i = 0; i < CUSTOMER; i++) {
 pthread_join(custid[i], NULL);
 }
//等待所有线程结束 回收资源 结束进程
 finish(&lamp);
 printf("+++++++++++++++++++++++++++++++++++++++++ \n");
 printf("+++++++++++++++ ALL OVER ++++++++++++++++ \n");
 printf("+++++++++++++++++++++++++++++++++++++++++ \n");
 return 0;
}
  • 5
    点赞
  • 16
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值