基于C++的音乐厅门票预定系统

一、实验要求

  • 利用IPC机制仿真一个音乐厅门票订售系统;该系统包含若干售票代理,这些代理连接到一个票务中心计算机

  • 每个代理可以看成是一个可并发执行的进程,如果某个代理企图订/售一个已被占用的座位,系统应该禁止该操作并打印“座位已占用”的提示信息。如果某交易涉及对不存在的座位进行操作,则系统也应该打印出错信息

  • 需要注意的是:购票之前无需先预订,而取消操作只有到涉及的座位被预订但尚未售出时候才有效

  • 为使结果显示更明晰,系统在每个交易完成后都应该给出交易的信息摘要,而在系统结束后则应该显示出座位的订售情况(包含客户信息)

二、实验环境

  • 系统平台:Ubuntu 64位,Windows10 64位

  • 集成开发环境:Visual Studio Community 2017

三、实验内容

3.1 程序框架

在这里插入图片描述

音乐厅座位状态用一个二维整型数组seat存储(1:可用,-1:预定0:售出),共享节中的数据变量seat(座位状态),flag,No(代理商编号),Lock(互斥访问标记)等会被多个进程共享,其值若在一个进程中被改变,则该操作对其它进程可见;

//--------------共享节------------------------------
# pragma data_seg("Shared")
volatile int seat[N][M] = {0};//存放音乐厅座位状态
volatile int flag = 1;//初始化标记
volatile int No = 1; //售票终端编号
volatile int Lock = 0;//0:文件关闭,1:文件打开
# pragma data_seg
# pragma comment(linker,"/Section:Shared,RWS")

票务中心包含以下操作:Set_ticket():购买票;Set_reserve():预定票;Set_cancel():取消票;Show_ticket():显示用户购买的票。Show_reserve():显示用户预定的票;Get_state():获得音乐厅座位的状态。

票务中心涉及到对座位状态seat、顾客预定单reserve、顾客购买单ticket的操作,是执行售票任务的最终操作者。

基本操作为通过seat[][]=value改变座位状态,然后从文件中载入顾客(预定/购买)订单,并用新的用户操作改变订单状态,然后将订单写入文件,并返回操作结果。至此通过共享节、文件、锁机制实现了进程之间的数据共享。

	seat[alphabet_To_number(in)][im] = 0;
	getticket();
	if (Iterator_ticket != ticket_record.end())//在订单中找到了顾客姓名
		ticket_record[customer].push_back(temp);	
	else //没有在订单中找到顾客姓名
		ticket_vector.push_back(temp);
	ticket_record.insert(map<string,vector<string>>::value_type(customer, ticket_vector));
}
giveticket();

售票代理Agent有一个成员变量Ticket_center,借此可以访问票务中心提供的接口函数,进行完整的音乐厅票务代理操作。

class Agent
{
private:
	Ticket_center T;
public:
	Agent(Ticket_center TT)
	{
		T = TT;
	}
	int reserve(int rows, int columns, string customer)
	{
		return T.set_reserve(rows, columns, customer);
	}
	int ticket(char rows, int columns, string customer)
	int cancel(int rows, int columns, string customer)
	void show_ticket(string customer)
	void show_reserve(string customer)
	int get_state(char rows, int columns)
}

3.2 程序运行流程

在这里插入图片描述

四、项目测试

编写测试脚本启动K个售票代理终端,在脚本中我们企图启动十几个终端进程,但是由于程序限定最多只能有K个售票代理,所以该脚本最多启动K个进程。

@echo off
start musichall.exe
ping 127.1 -n 2 >nul
•••

测试项目包括购票、订票、取消订票、显示顾客订单的测试,以及多个售票代理终端数据共享同步的测试。

4.1 程序正常启动,开启多个售票代理终端

程序包目录如下:

在这里插入图片描述

执行测试脚本启动多个终端:

在这里插入图片描述

可以清晰的看到每个终端的提示信息中显示了售票代理号,共打开6个终端,这也证明了进程间实现了数据共享。

4.2 购票测试(N=26,M=10,K=6)

测试用例:

ticket 4 gatsby;
ticket G gatsby;
ticket B 4 gatsby;
ticket C 4c gatsby;
ticket D 4r gatsby;
ticket F 4 8 gatsby;

ticket 4 gatsby:

在这里插入图片描述

ticket G gatsby:

在这里插入图片描述

tikket B 4 gatsby:

在这里插入图片描述

ticket C 4c gatsby:

在这里插入图片描述

ticket D 4r gatsby:

在这里插入图片描述

ticket F 4 8 gatsby:

在这里插入图片描述

4.3 预定票和取消票测试

测试用例:

reserve 4 bob;
reserve B 4c bob;
cancel  ** bob;

reserve 4 bob:

在这里插入图片描述

reserve B 4c bob:

在这里插入图片描述

cancel ** bob:

在这里插入图片描述

4.4 显示顾客订单和代理数据共享同步测试

测试用例:

reserve 5 joy;
ticket 5 joy;
show all joy;

1号代理 reserve 5 joy:

在这里插入图片描述

2号代理 ticket 5 joy:

在这里插入图片描述

3号代理show all joy:

在这里插入图片描述

五、实验心得

之前我写的许多程序基本上都是单进程的,几个函数要共享变量就使用全局变量或其他方法,相对来说比较简单和容易理解。第一次写多进程程序,并且还要实现多个进程之间的数据共享,想想还是比较麻烦的。然而通过百度和其他工具我找到了实现共享的方法,有许多种,最终选择了最好实现的一种方法完成了多进程程序的编写。

对程序的编写也有了更近一步的理解,编写程序之前对项目需求的透彻理解可以辅助建立完整的框架,并对选择什么工具和方法提供更好的参考,这一点很重要。

猜你喜欢

转载自blog.csdn.net/newlw/article/details/125047065
今日推荐