Linux操作系统利用信号量实现银行叫号排队系统

上传人:n**** 文档编号:37366983 上传时间:2018-04-15 格式:DOCX 页数:25 大小:593.81KB
返回 下载 相关 举报
Linux操作系统利用信号量实现银行叫号排队系统_第1页
第1页 / 共25页
Linux操作系统利用信号量实现银行叫号排队系统_第2页
第2页 / 共25页
Linux操作系统利用信号量实现银行叫号排队系统_第3页
第3页 / 共25页
Linux操作系统利用信号量实现银行叫号排队系统_第4页
第4页 / 共25页
Linux操作系统利用信号量实现银行叫号排队系统_第5页
第5页 / 共25页
点击查看更多>>
资源描述

《Linux操作系统利用信号量实现银行叫号排队系统》由会员分享,可在线阅读,更多相关《Linux操作系统利用信号量实现银行叫号排队系统(25页珍藏版)》请在金锄头文库上搜索。

1、 LinuxLinux 操作系统课程设计操作系统课程设计题目:题目:进程通信与进程同步机制实践进程通信与进程同步机制实践(银行叫号排队模拟系统)(银行叫号排队模拟系统)所在学院: 所在班级: 学生姓名: 学生学号: 指导教师: 一、题目一、题目某银行提供 5 个服务窗口(3 个对私服务窗口,1 个对公服务窗口,1 个理财服务窗口)和 10 个供顾客等待的座位。顾客到达银行时,若有空座位,则到取号机上领取一个号,等待叫号;若没有空座位,则在门外等待或离开。取号机每次仅允许一位顾客使用,有对公、对私和理财三类号,每位顾客只能选取其中一个。当营业员空闲时,通过叫号选取一位顾客,并为其服务。请用 P、

2、V操作写出进程的同步算法。二、目的二、目的1、 掌握基本的同步与互斥算法 。2、学习使用 Linux 中基本的同步对象,掌握相关 API 的使用方法。 3、了解 Linux 中多任务的并发执行机制,实现进程的同步与互斥 。三、实验环境三、实验环境Linux CentOS、Ubuntu、Fedora 等 Linux 系统编译器 GCC编程语言 C 语言四、要求四、要求1、当有顾客取号的时候,不允许其他顾客取号。2、当服务窗口满的情况下,其他人必须等待。3、当没有顾客的情况下,服务窗口必须等待。4、打印:A、 初始状态B、 中间变化的状态信息C、以及最终状态信息。五、原理及算法五、原理及算法本程序

3、中设计 6 个信号量,其中 signal_A、signal_B 和 signal_C 分别是对私、对公、理财窗口的同步信号量。若信号量值的等于 0,说明当前没有空闲空口,顾客需要等待。另设置一个 signal_seat 同步信号量,记录当前的座位情况,若该信号量等于 0,说明当前没有空座位,顾客需要等待。另有一个signal_customer 同步信号量用于记录当前已经取过票的总人数,用于生成票号信息。还有一个 mutex 互斥信号量,用于实现各进程在对信号量进行操作时的互斥。顾客进入银行之后,先看通过一个依据系统时间的随机数来确定自己是需要对私、对公还是理财服务(在本程序中分别对应于 A 类

4、顾客,B 类顾客和 C类顾客) ,这三个类型的顾客的比例为 3:1:1.然后顾客根据自己需要的服务类型,查看提供相应类型服务的窗口是否空闲,若窗口有空闲,则系统直接按照signal_customer 记录的信息,生成票面信息;若窗口没有空闲,则再去查看signal_seat 信号量看看是否有空座位,若有空座位,则根据 signal_customer记录的信息,生成票面信息;若没有空座位,则通过一个以系统时间为种子的随机数生成器生成一个随机数,帮助顾客确定是要继续等待还是离开,这两种情况的比例为 1:1.若顾客选择离开,则相应的进程退出。当顾客取到票后,便开始查看对应类型的窗口是否有空闲,如果有

5、空闲,则上前办理业务。顾客办理业务需要的时长通过以系统时间为种子的随机数生成器来确定,时长均在 10 秒到 60 秒之间。在程序执行的过程中,顾客的状态每有变换,都会有相应的输出提示信息,并在输出的行尾输出发生该动作时当前的系统时间,以便于我们分析各个顾客进程的执行情况。本实验在 Linux 环境下完成,该程序是通过进程实现的。包含一个service 可执行文件,一个 customer 可执行文件和一个 deletesem 可执行文件。其中 service 可执行文件用于在内存中申请一个共享内存空间,并将这个内存空间与自身进程绑定;customer 可执行文件每执行一次,就增加一个进程,即代表

6、有一位顾客来到。通过多次执行 customer 可执行文件来模拟多位顾客;deletesem 可执行文件用于在 service 进程和 customer 进城都执行完毕后,删除内存空间中的信号集。实验中利用 GCC 编译器,通过编写 Makefile 文件来快速编译源代码生成以上三个可执行文件。六、程序中各主要函数说明六、程序中各主要函数说明1 1、intint createshm(createshm( charchar * * pathname,pathname, intint proj_id,proj_id, size_tsize_t size)size)创建共享内存的函数,操作成功则返回

7、共享内存标识符,失败返回-1.2 2、intint createsemcreatesem (const(const charchar * * pathname,pathname, intint proj_id,proj_id, intint members,members, intint init_val)init_val)在共享内训中创建信号量的函数,操作成功则返回信号集标识符,失败返回-1.3 3、intint opensem(constopensem(const charchar * * pathname,pathname, intint proj_id)proj_id)打开信号集函数,

8、操作成功则返回信号集标识符,失败返回-1.4 4、intint sem_p(intsem_p(int semid,semid, intint index)index)P 操作函数,操作成功则返回 0,失败返回-1.5 5、intint sem_v(intsem_v(int semid,semid, intint index)index)V 操作函数,操作成功则返回 0,失败返回-1.6 6、intint wait_sem(intwait_sem(int semid,semid, intint index)index)等待信号量为 1 函数,操作成功返回 1.7 7、intint delete_

9、semdelete_sem (int(int semid)semid)删除信号集函数,操作成功返回 0.8 8、intint get_sem_valget_sem_val (int(int semidsemid ,int,int index)index)获取指定信号集中指定下标的信号量的值,操作成功返回该信号量的值。9 9、intint my_random()my_random()自定义随机数生成器,以系统时间为种子,每次执行前延时 1 秒,以便于生成不同的随机数。1010、voidvoid print_time()print_time()打印当前系统时间。1111、intint get_ti

10、cket(intget_ticket(int semid,semid, charchar identifyLabel,identifyLabel, intint * * ticket,ticket, intint * * flag)flag)顾客取票函数,取票成功,返回 1,失败返回-1,,由于没有空座,顾客选择离开则返回 0。1212、voidvoid service(intservice(int semid,semid, charchar identifyLabel,identifyLabel, intint * * ticket,ticket, intint *flag)*flag)顾客

11、办理业务函数。七、源程序清单七、源程序清单sharemem.h 文件文件#include#include#include#include#include#include#include#include#include#define SHM_SIZE 1024#define INDEX_MUTEX 0#define INDEX_SIGNAL_SEAT 1#define INDEX_SIGNAL_CUSTOMER 2#define INDEX_SIGNAL_A 3#define INDEX_SIGNAL_B 4#define INDEX_SIGNAL_C 5/*定义信号量*/*同步信号量一共有 4

12、 个*/ int signal_A=3, signal_B=1, signal_C=1, signal_seat=3, signal_customer=0; /*互斥信号量 mutex 控制进程对每个同步信号量的操作*/ int mutex=1;int signal_count=6;/信号量计数器,记录一共有多少信号量union semunint val;struct semid_ds * buf;unsigned short * array;/*创建共享内存函数*/int createshm( char * pathname, int proj_id, size_t size)key_t s

13、hmkey;int sid;/*获取键值*/if (shmkey=ftok(pathname, proj_id)=-1)perror (“ftok error!n“);exit(1);return -1;if (sid=shmget(shmkey, size, IPC_CREAT | 0666)=-1)perror (“shmget call failed.n“);exit(1);return -1;return (sid);/*定义创建信号量的函数*/int createsem (const char * pathname, int proj_id, int members, int ini

14、t_val)key_t msgkey;int index,sid;union semun semopts;if (msgkey=ftok(pathname, proj_id)=-1)perror (“ftok error!n“);exit(1);return -1;if(sid=semget(msgkey, members, IPC_CREAT | 0666)=-1)perror (“semget call failed.n“);exit(1);return -1;/*对信号量进行初始化操作*/for(index=0;index 0)/检查,如果有空窗口,则直接取票,不用判断座位*flag=0

15、;/将标志为设为 0,标示没有顾客在等待,不用排队goto goto_A;/跳转到直接取票if( wait_sem(semid, INDEX_SIGNAL_SEAT) )/如果没有空座,则等待空座sem_p(semid, INDEX_SIGNAL_SEAT);goto_A: if( wait_sem(semid, INDEX_MUTEX) )/等待操作信号量释放sem_p(semid, INDEX_MUTEX);/锁定操作信号量*ticket=get_sem_val(semid, INDEX_SIGNAL_CUSTOMER) + 1;/分配票号(票号是根据当天的总顾客数排的)wait_num = (signal_seat - get_sem_val(semid,INDEX_SIGNAL_SEAT) ) -1;/获取当前等待的人数printf(“号码:A%03d,“,*ticket);if(wait_num=0 | *flag=0)printf(“当前没有顾客正在等待。t“);/wait_num 大于等于 0 或者 flag 大于 0,表示当前无人等待print_time();elseprintf(“有%d 位顾客正在等待。t“,wait_num);print_time();printf(“顾客 A%03d 正

展开阅读全文
相关资源
相关搜索

当前位置:首页 > 电子/通信 > 综合/其它

电脑版 |金锄头文库版权所有
经营许可证:蜀ICP备13022795号 | 川公网安备 51140202000112号