描述
面包师有很多面包和蛋糕,由 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;
}