描述

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

面包师问题--linux实现相关推荐

  1. 进程间通信之面包师问题

    作者:潘家邦 2012年12月6日 面包师问题是进程间通信的经典问题.本文就面包师问题进行讨论,并在linux上编程实现.平台说明:Linux Mint 14,G++ 4.7.2. 问题描述 面包师有 ...

  2. 理发师多线程实现----面包师多进程实现

    理发师问题的实现,多线程. Linux 理发师.面包师程序文档 理发师问题 有一个理发师,一把理发椅和4把供等候理发的顾客坐的椅子.如果没有顾客,则理发师便在理发师椅子上睡觉:当一个顾客到来时,必须唤 ...

  3. Linux课程project----基于c/c++

    Linux课程project----基于c/c++ 写在前面:Linux课程大作业,实现生产者/面包师,售货员与消费者的业务逻辑的程序. 题目大概要求:面包师为守护进程并添加服务,且是多线程程序.售货 ...

  4. 过滤Linux下不同大小的文件,linux查找当前目录下 M/G 大小的文件,删除Linux下指定大小的文件

    过滤Linux下不同大小的文件,linux查找当前目录下 M/G 大小的文件,删除Linux下指定大小的文件 find ./ -type f -size +1G| xargs rm 在清理系统日志文件 ...

  5. linux环境下nacos的安装+启动,阿里云服务器安装nacos

    nacos安装+启动(linux环境): 基础:安装java环境 官网下载压缩包:如 nacos-server-1.2.1.tar.gz 放在自定义目录下 # 解压 tar -xvf nacos-se ...

  6. Alibaba Cloud Linux 2.1903 LTS 64位服务器yum源下载404,Alibaba Cloud Linux 2实例中使用docker-ce、epel等YUM源安装软件失败

    [Alibaba Cloud Linux 2.1903 LTS 64位]服务器yum源下载404 failure: repodata/repomd.xml from docker-ce-stable: ...

  7. Linux下创建硬链接,文件访问为空,提示:xxxx: 符号连接的层数过多

    Linux下创建软链接|硬链接,文件访问为空,提示:x x x: 符号连接的层数过多. 原因:创建符号链接的时候未使用绝对路径,无论是源文件路径还是目标路径,都需要使用绝对路径. 如: ln -s / ...

  8. 作为一个java程序员,常用的linux命令(越攒越多)

    本篇记录我在工作中不断遇到的常用的linux命令,并进行总结,时常更新! 1. 升级服务时先停止服务,然后进行替换 linux中杀进程时候,如果你是知道它所占用的端口号的话,可以通过 netstat ...

  9. 设置linux初始root密码

    简单一步设置linux第一个root密码 sudo passwd root #输入当前账户密码 #输入准备设置的root密码 #确认密码 如下所示:

最新文章

  1. 玩Android微信小程序版
  2. python脚本自动运行失败_解决Python中定时任务线程无法自动退出的问题
  3. osgi框架和spring区别_最新100道大厂高频spring面试题附答案
  4. Android开机自启动 .
  5. Linux下Tomcat死活找不到JSP页面中import指定类的解决方法
  6. Java会走向晦暗吗?Kotlin会取而代之吗
  7. 诗人最近都很忙,忙着去远方了
  8. c++学习笔记---指针
  9. 如何下载哔哩哔哩视频
  10. CNN结构:色温-冷暖色的定义和领域区分(一)
  11. 中小企业OA系统自动办公软件
  12. php 微信发红包,php实现微信红包代码
  13. html5 mp4转换ogv格式,如何将mp4视频转换成ogv高清视频呢
  14. 联想电脑重装系统总结
  15. php标签打印机,PHP连接打印机
  16. tkinter可视化天气查询
  17. 华为8xmax升级鸿蒙系统,华为新系统发布在即,35款机型率先体验,看看你的手机在其中吗...
  18. Linux中的管道与连接符号
  19. C++界面开发框架Qt新手入门指南 - 如何创建Qt Quick UI项目
  20. xray和rad或burp联动

热门文章

  1. 不想被时代淘汰?网络工程师未来的出路在这里!
  2. 解决小程序自定义导航栏和右边胶囊高度一致
  3. python helper函数_使函数定义以python文件顺序独立
  4. 【AT91SAM7X-EK开发板】系统时钟的配置
  5. [转载]《武林外传》每一集都教会我们一个道理
  6. python修炼之pip基本命令
  7. 轻松熊喵喵 -- 名词解释(自用)
  8. 再见,仙剑之父!再见,姚壮宪!
  9. CellID 基站定位
  10. php sequelize,egg.js整合数据库ORM框架Sequelize