上次做完第一个程序小练习,今天我们在之前的基础上再提高一下难度。
窗口服务指示系统2:
继续上述情景,假如每个客户业务的处理时间为随机(1-3秒,业务生成时确定任务处理时间),同时需要对排队客户进行服务(同一窗口,不同用户有重复的业务请求),当窗口全满时,停止接受新客户的业务,待窗口空置数超过一半时恢复业务请求,统计哪项业务最受欢迎,及其平均处理时间(每十单统计)
分析:我们可以使用一个32位的整型数据来存放数据,一到四个字节分别用来存放当前处理完的任务、排队且生成1秒业务时间的任务、排队且生成1秒业务时间的任务、排队且生成1秒业务时间的任务,而每个字节上的八位来存放窗口号,即
// 3s 2s 1s 0s
00000000 00000000 00000000 00000000
每确定一个业务时间都移到相应的字节上,比如定义unsigned int wait,在4号窗口生成2秒的业务,则
wait|= 0x01<<(4-1)<<2*8,处理完一秒后再往右移动八位wait>>8。
代码:
#include <stdio.h>
#include <stdbool.h>
int main(int argc,char *argv[])
{
bool Busy = false;
unsigned char busycount = 0;
unsigned char window = 0;
unsigned char Wstate = 0; //窗口状态
unsigned char Wait = 0; //窗口等待状态
unsigned char Rsn = 0; //业务序号
unsigned char count = 0; //循环计数变量
unsigned char Timeout= 0; //超时计数
unsigned char Ptime = 0; //业务受理时间
unsigned int ProcessState = 0; //窗口处理进度,共4个字节,每个字节代表一个秒数有那些窗口处理完成
//4个字节表示对应的四秒时间,这八个窗口正在受理的业务将在哪一秒完成
srand((unsigned int)time(0));
while(1) //只要窗口未满
{
Timeout++; //超时计数
//窗口状态更新,客户的业务处理时间为 1-3 s
for(window=0;window<8;window++)
{
if(ProcessState & (0x1 << window) ) //检查当前时刻是否有任务处理完成
{
if(Wait &(0x1 << window)) //该窗口已有等待客户,则开始受理
{
//对任务完成后的的下一位原等待用户进行任务时间受理
Ptime = rand()%3+1; //生成受理时间,1-3
//如果满足响应条件,更新处理进度指示 // 3s 2s 1s 0s
ProcessState |= ((0x1<<window) <<(Ptime*8)); //假如生成随机业务Rsn窗口为2,处理时间Ptime为3s 00000000 00000000 00000000 00000000
}
else
{
busycount--;
if(Busy && busycount <= 4)
Busy = false;
}
}
}
Wstate &= ~(ProcessState&0xFF);//将当前服务到期的任务指示位清零,ProcessState最低字节指示当前秒需要完成任务的窗口
Wstate |= Wait; //判断当前是否有等待用户,先处理原等待用户,将正在等待的窗口指示位更新到Wstate指示位
//因为原客户受理完毕后,已等待客户需要优先补位,方可接受新客户
Wait &= ~(ProcessState&0xFF);//如果有等待客户,则先清除原窗口等待指示位,因为等待客户已经补位进入受理状态
printf("clear Wait = %x \n",Wait);
ProcessState >>= 8; //每隔1s,根据最低字节服务指示进行完成操作,更新当前的处理进度指示位 (最低字节右移)
sleep(1); //每隔1s
if(Timeout%2 == 0 && !Busy)
{
//接受新用户
Rsn = rand()%8; //生成业务编码,对应窗口0-7
Ptime = rand()%3+1; //生成受理时间,1-3
printf("Rsn = %x Ptime = %x \n",Rsn,Ptime);
if(((Wstate>>Rsn) & 0x1) == 0x1) //判断目标窗口是否繁忙
{
Wait |= (0x1 << Rsn); //如果正忙,则往该窗口的等待指示位置1
printf("set Wait = %x \n",Wait);
}
else
{
//如果满足响应条件,更新处理进度指示 // 3s 2s 1s 0s
ProcessState |= ((0x1<<Rsn) <<(Ptime*8)); //假如生成随机业务Rsn窗口为2,处理时间Ptime为3s 00000000 00000000 00000000 00000000
// 00000100 00000000 00000000 00100100
Wstate |= (0x1 << Rsn);
busycount++;
if(!Busy && busycount==8)
Busy = true;
}
}
/*************************遍历窗口,更新服务状态******************************/
for(window = 0; window < 8; window++)
{
if(Wstate & (1 << window))
{
printf("%d号窗口服务中",window + 1);
}
else
{
printf("%d号窗口空闲",window + 1);
}
if(Wait & (1 << window))
{
printf(" %d号窗口排队中",window + 1);
}
printf("\n");
}
if(Busy)
{
printf("当前业务繁忙,暂停接受新业务\n");
}
else
{
printf("业务服务正常\n");
}
printf("\n");
}
return 0;
}
大家好好研究一下,如果有什么写错的或者你们有更好的做法,都可以跟我讨论一下。