实现功能:
用一个栈存储楼层的信息,即电梯所到的高度,初始化栈,即定义楼的高度;
用队列来记录乘客的信息,运送的乘客插入到队列中去,送完的乘客从队列中删除;
开双线程,一个记录电梯运行时间,另一个处理乘客信息,并与电梯信息相关联;
具体体现如下:
/***************************************************************/
/*************************注意!!!******************************/
/*******此代码是在linux环境下编写,所调用的回调函数是调用linux系统下的****/
/***************************************** 刘春辉****************/
/***************************************2014.01.12**************/
/***************************************************************/
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <time.h>
#include <pthread.h>
#include <sys/time.h>
#include <signal.h>
#define SElemType Floor
#define ERROR 0
#define OK 1
#define STACKINCREMENT 10 //增加楼层高度时扩充的数组大小的值
/*楼层结建立*/
int infloor; // 进入楼层层数
int outfloor; // 去的楼层层数
int beartime; // 人容忍等候的时间
int intertime; //下一个人出现的时间间隔
int FLOOR = 0; //记录电梯所到楼层数的变量,初始状态1
int FLOORGAP = 0; // 电梯所在楼层与人所在楼层的楼层数差距
int USETIME = 0; // 人上楼所用的时间
int check_state = -1; //查看电梯运行状态控制变量
int menu = 0; // 控制查看电梯运行状态的按钮
void* thread_customer(void*);
void callback(int);
pthread_t th1 = 0;
pthread_t th2 = 0;
pthread_mutex_t mutex;
int new_tot = 0;
int passed_time = 0;
int times = 0;
typedef struct Floor
{
int floor; //电梯的当前位置(楼层)
int D1; //值为0,除非人们正在进入和离开电梯
int D2; //值为0,如果电梯在某层听候300t以上
int D3; //值为0,除非电梯门正开着又无人进出电梯
char State[10]; //电梯的当前状态
Floor *next;
}Floor;
/****建立(楼层)栈的结点*****/
typedef struct
{
SElemType *base; //栈底
SElemType *top; //栈顶
int stacksize; // 栈的长度
}SqStack;
SqStack Stack; // 定义(电梯信息)栈
/*****初始化(楼层)栈******/
int InitStack(SqStack &S,int num)
{
S.base = (SElemType *)malloc(num * sizeof(SElemType));
if(!S.base)
return ERROR;
S.top = S.base;
S.stacksize = num;
return OK;
}
/******插入(楼层)栈的元素******/
int Push(SqStack &S,int e)
{
if(S.top - S.base >= S.stacksize)
{
S.base = (SElemType *)realloc(S.base,(S.stacksize+STACKINCREMENT)*sizeof(SElemType));
if(!S.base)
return ERROR;
S.top = S.base + S.stacksize;
S.stacksize += STACKINCREMENT;
}
S.top->floor = e;
S.top->D1 = 0;
S.top->D2 = 0;
S.top->D3 = 0;
strcpy(S.top->State,"Idle");
++S.top ;
return OK;
}
/******输出(楼层信息)栈元素*****/
void PrintStack(SqStack &S)
{
printf("\n");
SElemType *p;
p = S.top - 1;
printf("floor D1 D2 D3 State\n");
while(p != S.base)
{
printf("%d %d %d %d %s\n",p->floor,p->D1,p->D2,p->D3,p->State);
p--;
}
printf("%d %d %d %d %s\n",p->floor,p->D1,p->D2,p->D3,p->State);
}
/********人信息头结点建立*****/
typedef struct Man
{
int InFloor; //进入哪个楼层
int OutFloor; // 要去的楼层
int GivenupTime; // 人能容忍的等候时间
int InterTime; //下一个人出现的时间间隔,据此系统预置下一个人进入系统的时刻
int timegap; // 从电梯位置到人的位置所用的时间的数值变量
int timeuse; // 人从所在楼层到目的楼层所用的时间
int timewait; // 电梯从上一个目标完成到现在这个目标的时间
Man *next;
}Man;
Man *man;
/****定义队列(个人信息)的头结点*****/
typedef struct ManQueue
{
Man *rear; // 队尾指针
Man *front; //对头指针
}ManQueue;
ManQueue Queue; // 定义(人信息)队列
/******初始化队列*****/
int InitQueue(ManQueue &Q)
{
Q.front = (Man*)malloc(sizeof(Man));
Q.rear = Q.front;
if(!Q.front)
return ERROR;
Q.front->next = NULL;
Q.front->InFloor = -1;
Q.front->InterTime = -1;
Q.front->OutFloor = -1;
Q.front->GivenupTime = -1;
return OK;
}
/*****销毁队列*****/
int DestroyQueue (ManQueue &Q)
{
while(Q.front)
{
Q.rear = Q.front->next;
free(Q.front);
Q.front = Q.rear;
}
return OK;
}
/******插入队列结点*******/
int EnQueue(ManQueue &Q,int infloor,int outfloor,int beartime,int intertime,int tg,int tu,int tw)
{
Man *p;
p = (Man*)malloc(sizeof(Man));
if(!p)
return ERROR;
p->next = NULL;
p->InFloor = infloor;
p->InterTime = intertime;
p->OutFloor = outfloor;
p->GivenupTime = beartime; // 容忍时间
p->timegap = tg;
p->timeuse = tu;
p->timewait = tw;
Q.rear->next = p;
Q.rear = p;
return OK;
}
/******返回人所到楼层的信息******/
int Out_Floor(ManQueue &Q)
{
return Q.front->next->OutFloor;
}
/*******删除队列元素*******/
int DeQueue(ManQueue &Q)
{
Man *p;
if(Q.front == Q.rear)
return ERROR;
p = Q.front->next;
Q.front->next = p->next;
if(Q.rear == p) //判断队列是否为空
Q.rear = Q.front;
free(p);
return OK;
}
/******输出队列(人信息)*****/
void PrintQueue(ManQueue &Q)
{
Man *m;
m = Q.front->next;
printf("InFloor OutFloor GivenupTime InterTime\n");
while(m != Q.rear)
{
printf("%d\t%d\t%d\t%d\n",m->InFloor,m->OutFloor,m->GivenupTime,m->InterTime);
m = m->next;
}
printf("%d\t%d\t %d\t%d\n",m->InFloor,m->OutFloor,m->GivenupTime,m->InterTime);
}
/**** 判断容忍时间和电梯所到达时间的关系 ****/
int JudgeTime()
{
int time;
if(Queue.front != Queue.rear)
{
Man *m;
m = Queue.front->next;
while(m != Queue.rear)
{
time = m->timegap + m->timeuse;
m = m->next;
}
time = m->timegap + m->timeuse;
}else
{
if( FLOORGAP >= 0)
{
return FLOORGAP * 15;
}else
{
return (FLOORGAP * -1) * 15;
}
}
return time;
}
/*****电梯完成上个任务后到达现在路程所用时间*****/
int Time_Wait(int it)
{
if((Queue.rear->OutFloor - it) >= 0)
{
return 23 * (Queue.rear->OutFloor - it);
}else
{
return 14 * (it - Queue.rear->OutFloor);
}
}
/****判断乘客乘坐电梯时所花费的时间********/
int Use_Time(int infloor,int outtime)
{
if((infloor - outtime) > 0)
{
return 23 * (infloor - outtime);
}else
{
return 14 * (outtime - infloor);
}
}
int main()
{
int sum,i;
int TIMEGAP; // 电梯所在楼层与人所在楼层的时间差距
int up_leave_time = 0; // 电梯送人所用的时间
int TIMEWAIT = 0; // 电梯从上个任务完成后到达现在位置的路程所用的时间
InitQueue(Queue); //初始化(人信息)队列
struct itimerval timer_struct;
timer_struct.it_value.tv_sec = 0;
timer_struct.it_value.tv_usec = 500000; // the SIGALRM signal will be sent after 10,000 ms.
timer_struct.it_interval.tv_sec = 0;
timer_struct.it_interval.tv_usec = 500000;
signal(SIGALRM, callback); // register signal handler
setitimer(ITIMER_REAL, &timer_struct, NULL);
pthread_create(&th2, NULL, thread_customer, NULL);
printf("\t\t电梯系统\n\n");
printf("输入楼层层数:");
scanf("%d",&sum);
if(InitStack(Stack,sum)) // 初始化(楼层)栈
{
/*********初始化楼层高度**********/
for(i = 1;i <= sum;i++)
{
if(Push(Stack,i) == 0)
{
printf("初始化楼层失败!");
}
}
printf("\n输出电梯的基本信息:\n");
PrintStack(Stack); // 打印电梯信息
FLOOR = 1; //初始化电梯现在所在的楼层
while(1)
{
printf("请输入您要进入的楼层:");
scanf("%d",&infloor);
if(infloor > 0 && infloor <= sum) // 判断输入所在楼层条件是否合法
{
printf("请输入您要去的楼层:");
scanf("%d",&outfloor);
if(outfloor > 0 && outfloor <= sum) // 判断到达楼层的条件是否合法
{
printf("请输入你能容忍等候的时间:");
scanf("%d",&beartime);
printf("下一人出现的时间间隔:");
scanf("%d",&intertime);
FLOORGAP = FLOOR - infloor; // 电梯所在位置与人所在位置之间的差距
TIMEGAP = JudgeTime(); // 电梯到达人的位置时所花费的时间
if(TIMEGAP <= beartime) // 判断容忍时间与电梯到达时间的关系
{
/******查看电梯运行的状态********/
printf("是否查看电梯当前运行的状态?(1.是 2.否)\n");
scanf("%d",&check_state);
menu = 0;
printf("请按'1'回到系统界面:\n\n");
scanf("%d",&menu);
up_leave_time = Use_Time(infloor ,outfloor); //乘客乘电梯所花费的时间
TIMEWAIT = Time_Wait(infloor); // 电梯送完前一个人后到达现在这个人时所用的时间
EnQueue(Queue,infloor,outfloor,beartime,intertime,TIMEGAP,up_leave_time,TIMEWAIT); // 人的信息符合要求,入队
man = Queue.front->next;
printf("当前乘客的的信息:\n");
PrintQueue(Queue); // 输出(人信息)队列
}else
{
printf("电梯到达时间超过容忍时间,放弃乘坐电梯!\n");
}
}else
{
printf("输入的楼层不合法!\n");
}
}else
{
printf("输入的楼层不合法!\n");
}
}
}else
{
printf("初始化楼层失败!");
}
return 0;
}
void* thread_customer(void * data) {
while(1)
{ }
}
void callback(int sig) {
if(Queue.front != Queue.rear)
{
if(check_state == 1 && menu != 1)
{
if(man->timewait > 0)
{
printf("电梯还有%d秒到达%d楼\n",man->timewait,man->InFloor);
man->timewait --;
}else if(man->timewait == 0 && man->timeuse > 0)
{
printf("电梯还有%d秒到达%d楼\n",man->timeuse,man->OutFloor);
man->timeuse--;
}else if(man->timewait == 0 && man->timeuse == 0)
{
printf("电梯此时在%d楼\n",man->OutFloor);
if(man == Queue.rear)
{
if(man->timewait > 0)
{
printf("电梯还有%d秒到达%d楼\n",man->timewait,man->InFloor);
man->timewait --;
}else
{
check_state = 0;
menu = 0;
}
}else
{
man = man->next;
}
FLOOR = Out_Floor(Queue); // 现在电梯所在的楼层
DeQueue(Queue); // 将此人信息从队列中删除
}
}else
{
if(man->timewait > 0)
{
man->timewait --;
}else if(man->timewait == 0 && man->timeuse > 0)
{
man->timeuse--;
}else if(man->timewait == 0 && man->timeuse == 0)
{
if(man != Queue.rear)
{
man = man->next;
FLOOR = Out_Floor(Queue); // 现在电梯所在的楼层
DeQueue(Queue); // 将此人信息从队列中删除
}else
{
if(man->timewait > 0)
man->timewait --;
}
}
}
}else if(check_state == 1)
{
printf("您是第一位乘客\n\n");
check_state = 0;
menu = 0;
}
}