队列指针

2019-07-14 09:01发布

以前队列学的就不太好,用队列的时候只知道用动态链表,做操作系统的进程调度时,百度到了一个程序,发现这个程序用的队列非常简洁且实用,因此摘录下来了,算是补一下学习数据结构时遗留的漏洞吧。代码如下:   #include #define N 10     //系统中所允许的最大进程数量
#define SLOT 5   //时间片大小 //进程状态枚举 
typedef enum
{
 Running,     //运行状态
 Aready,      //就绪状态
 Blocking     //阻塞状态 } ProStatus; //进程控制块
typedef struct
{
 int name;                  //进程标识符
 ProStatus status;          //进程状态
 int ax,bx,cx,dx;           //通用寄存器
 int pc;                    //程序计数器寄存器
 int psw;                   //程序状态字寄存器
 int next;                  //指向下一个进程的指针
} PCB; //就绪队列指针   没有用设置多个链表,直接用一个数组,不用下标表示不同的队列
typedef struct         
{
 int head;            //头指针
 int tail;            //尾指针
} Ready;
//模拟寄存器
int PSW,AX,BX,CX,DX,PC,TIME; //PCB的静态链表
PCB pcbArea[N];          //模拟PCB区域的数组
int run;                 //运行状态程序的指针
Ready ready;             //就绪队列指针             
int pfree;               //空闲队列的指针  //初始化运行状态进程指针
void InitRun()
{
 run=-1;
}
 
 //初始化就绪状态队列
void InitReady()
{
 ready.head=ready.tail=-1;
}  //初始化空闲队列
void InitFree()
{
 int temp;
 for(temp=0;temp  {
  pcbArea[temp].next=temp+1;
 }
 pcbArea[temp].next=-1;  pfree=0;
}  //就绪队列出队
int PopReady()          //返回结点在PCB区域数组的编号
{
 int temp;
 if(ready.head==-1)
 {
  printf("就绪队列为空,不能出队。/n");
  return -1;
 }
 temp=ready.head;
 ready.head=pcbArea[temp].next;
 if(ready.head==-1)
  ready.tail=-1;
 pcbArea[temp].next=-1;//NEXT域为-1时表示不再就绪队列上了
 return temp; }  //空闲队列出队
int PopFree()          //返回结点在PCB区域数组的编号
{
 int temp;   
 if(pfree==-1) 
 {
  printf("空闲队列为空,不能出队。/n");
  return -1;
 }
 
 temp=pfree;
 pfree=pcbArea[temp].next;//此时空闲队列应该指向下一个了
 pcbArea[temp].next=-1;
 return temp;
}  //就绪队列入队
void PushReady(int x)          //x为入队结点的编号
{
 int temp;
 if(ready.head==-1)
 {
  ready.head=x;
  ready.tail=x;
 }
 else
 {
  temp=ready.tail;
  ready.tail=x;
 }
 pcbArea[ready.tail].next=-1;
} //创建PCB
void CreatePCB(int x,PCB pcb)         //x为要创建PCB在PCB区域数组的编号
{
 pcbArea[x].ax=pcb.ax;
 pcbArea[x].bx=pcb.bx;
 pcbArea[x].cx=pcb.cx;
 pcbArea[x].dx=pcb.dx;
 pcbArea[x].name=pcb.name;
 pcbArea[x].next=-1;
 pcbArea[x].pc=pcb.pc;
 pcbArea[x].psw=pcb.psw;
 pcbArea[x].status=pcb.status;
} //创建进程函数
void Create(PCB pcb)
{
 int temp;
 if(pfree==-1)
 {
  printf("空闲队列为空,不能创建进程。/n");
  return;
 }
 temp=PopFree();
 pcb.status=Aready;
 CreatePCB(temp,pcb);
 PushReady(temp);
} //进程调度函数
void Schedule()
{
 int temp;
 if(ready.head==-1)
 {
  printf("系统内没有进程可以调度。");
  return;
 }
 temp=PopReady();
 pcbArea[temp].status=Running;  TIME=SLOT;                            //恢复CPU现场
 AX=pcbArea[temp].ax;
 BX=pcbArea[temp].bx;
 CX=pcbArea[temp].cx;
 DX=pcbArea[temp].dx;
 PC=pcbArea[temp].pc;
 PSW=pcbArea[temp].psw;
 
 run=temp;             //将选中的进程赋给运行指针  printf("当前运行的程序:/n");          //输出调度结果
 printf("进程号:%d/n",pcbArea[run].name);
 printf("进程状态:%d/n",pcbArea[run].status);
 printf("寄存器内容:/nAX/tBX/tCX/tDX/tPC/tPSW/n");
 printf("%d/t%d/t%d/t%d/t%d/t%d/n",
  pcbArea[run].ax,pcbArea[run].bx,pcbArea[run].cx,pcbArea[run].dx,pcbArea[run].pc,pcbArea[run].psw); }
void main()
{
 int temp;
 PCB tmp_pcb;  printf("请输入进程号,以负数为结束(进程号应保持唯一)。/n/n按任意键进入输入模式:");
 getchar();  InitRun();
 InitReady();
 InitFree();  printf("请开始输入进程号:/n");
 while(1)
 {
  scanf("%d",&temp);   if(temp<0)
   break;
  tmp_pcb.name=temp;
  tmp_pcb.ax=temp;
  tmp_pcb.bx=temp;
  tmp_pcb.cx=temp;
  tmp_pcb.dx=temp;
  tmp_pcb.pc=temp;
  tmp_pcb.psw=temp;   Create(tmp_pcb); 
 }
 printf("/n");  Schedule();
}