注册 登录
编程论坛 数据结构与算法

时间片轮转调度算法,帮看下

米小兔 发布于 2013-04-10 16:21, 3448 次点击
自己又用C++修改了一个代码,可是执行出来的效果,不是我想要的。看哪位大神能给我下面写的修改正确啊,憋死了。。。。还是自己没学好吧。

include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <iostream.h>

typedef struct node
{
char name[10];     
int prio;         
int round;         
int cputime;      
int needtime;
int gettime;   
int count;         
char state;        
struct node *next;
}PCB;
PCB *finish,*ready,*tail,*run; //队列指针
int N;     //进程数

void firstin()
{
run=ready;      //就绪队列头指针赋值给运行头指针
run->state='R'; //进程状态变为运行态
ready=ready->next; //就绪队列头指针后移到下一进程
}

void interrupt()//第一个CPU占用时间等于下一个进程的到达时间
{
if(ready->cputime==(ready->next)->gettime)
{
    ready=ready->next;
    ready->state='W';
}

}

//输出标题函数
void prt1(char a)
{
if(toupper(a)=='P')  //优先级法
  cout<<" "<<endl;
cout<<"进程名 到达的时间 占用CPU时间 到完成还要的时间 轮转时间片 状态"<<endl;
}

//进程PCB输出
void prt2(char a,PCB *q)
{
if(toupper(a)=='P')  //优先级法的输出
  cout<<q->name<<"       "<<q->gettime<<"       "<<q->cputime<<"           "<<q->needtime<<"               "<<q->round<<"         "<<q->state<<endl;
}
//输出函数
void prt(char algo)
{
PCB *p;
prt1(algo);  //输出标题
if(run!=NULL)  //如果运行指针不空
  prt2(algo,run);  //输出当前正在运行的PCB
p=ready;  //输出就绪队列PCB
while(p!=NULL)
{
  prt2(algo,p);
  p=p->next;
}
p=finish;   //输出完成队列的PCB
while(p!=NULL)
{
  prt2(algo,p);
  p=p->next;
}
getchar();  //按住任意键继续
}
//时间片轮转的插入算法
void insert(PCB *q)
{
PCB *p1,*s,*r;
s=q;  //待插入的PCB指针
p1=ready;  //就绪队列头指针
r=p1;  //*r做p1的前驱指针
while(p1!=NULL)
  if(p1->round<=s->round)
  {
   r=p1;
   p1=p1->next;
  }
  if(r!=p1)
  {
   r->next=s;
   s->next=p1;
  }
  else
  {
   s->next=p1;  //否则插入在就绪队列的头
   ready=s;
  }
}
//优先级创建初
void create(char alg)
{
PCB *p;
int i,gettime,time;
char na[10];
ready=NULL;  
finish=NULL;
run=NULL;   
cout<<"输入进程名,到达时间及其需要运行的时间:"<<endl;
for(i=1;i<=N;i++)
{
  p=new PCB;
  cin>>na;
  cin>>gettime;
  cin>>time;
  strcpy(p->name,na);
  p->cputime=0;
  p->gettime=gettime;
  p->needtime=time;
  if(gettime=0){p->state='W';}
  else {p->state='F';}
  p->round=0;
  if(ready!=NULL)  
   insert(p);
  else
  {
   p->next=ready;  
   ready=p;
  }
  cout<<"输入进程名,到达时间及其需要运行的时间:"<<endl;
}
prt(alg);  
run=ready;  
ready=ready->next;
run->state='R';
}
void timeslicecycle(char alg)
{cout<<"请输入时间片长度:";
int pertime;
cin>>pertime;
cout<<"输入时间片长度:"<<pertime<<endl;
while(run!=NULL)
{
  if(run->needtime>pertime)
    {
      run->cputime=run->cputime+pertime;
      run->needtime=run->needtime-pertime;
      run->round=run->round+pertime;
      run->state='W';
      interrupt();
      insert(run);
      interrupt();
      firstin();
    }
  else
   { int replace1,replace2;
     replace1=0;
     replace2=run->needtime;
     run->cputime=run->cputime+replace2;
     run->needtime=replace1;
     run->round=run->round+replace2;
     run->next=finish;
     finish=run;
     run->state='F';
     run=NULL;
     interrupt();
     if(ready!=NULL)
       firstin();
   }
  prt(alg);
}
}


//主函数
void main()
{
char algo='P';  //算法标记
cout<<"输入进程的个数:";
cin>>N;  //输入进程数
create(algo);  //创建进程
timeslicecycle(algo);  //优先级法调度
} //main()

这个代码,想要的结果,我打个比方,

输入进程的个数:4
输入进程名,到达时间及其需要运行的时间:
a 0 5
输入进程名,到达时间及其需要运行的时间:
b 1 3
输入进程名,到达时间及其需要运行的时间:
c 2 1
输入进程名,到达时间及其需要运行的时间:
d 3 6


进程名  到达的时间  占用cpu时间 到完成还要得时间 轮转时间片  状态
a       0            0           5               0           W
b       1            0           3               0           F
c       2            0           1               0           F
d       3            0           6               0           F
输入时间片长度:2
输入时间片长度为:2

进程名  到达的时间  占用cpu时间 到完成还要得时间 轮转时间片  状态
b       1            0           3               0           R
c       2            0           1               0           W
a       0            2           3               2           W
d       3            0           6               0           F

进程名  到达的时间  占用cpu时间 到完成还要得时间 轮转时间片  状态
c       2            0           1               0           R
a       0            2           3               2           W
d       3            0           6               0           W
b       1            2           1               2           W

进程名  到达的时间  占用cpu时间 到完成还要得时间 轮转时间片  状态
a       0            2           3               2           R
d       3            0           6               0           W
b       1            2           1               2           W
c       2            1           0               1           F

进程名  到达的时间  占用cpu时间 到完成还要得时间 轮转时间片  状态
d       3            0           6               0           R
b       1            2           1               2           W
c       2            1           0               1           F
a       0            4           1               4           W

进程名  到达的时间  占用cpu时间 到完成还要得时间 轮转时间片  状态
b       1            2           1               2           R
c       2            1           0               1           F
a       0            4           1               4           W
d       3            2           4               2           W

进程名  到达的时间  占用cpu时间 到完成还要得时间 轮转时间片  状态
a       0            4           1               4           R
d       3            2           4               2           W
b       1            3           0               3           F
c       2            1           0               1           F

进程名  到达的时间  占用cpu时间 到完成还要得时间 轮转时间片  状态
d       3            2           4               2           R
a       0            5           0               5           F
b       1            3           0               3           F
c       2            1           0               1           F

进程名  到达的时间  占用cpu时间 到完成还要得时间 轮转时间片  状态
d       3            4           2               4           R
a       0            5           0               5           F
b       1            3           0               3           F
c       2            1           0               1           F

进程名  到达的时间  占用cpu时间 到完成还要得时间 轮转时间片  状态
d       3            6           0               6           F
a       0            5           0               5           F
b       1            3           0               3           F
c       2            1           0               1           F

调度完成。。是这样一个意思
41 回复
#2
米小兔2013-04-10 18:30
我去- - ,难道没有高手吗?高手都哪去了。。。求解答啊!头炸了!
#3
azzbcc2013-04-10 18:40
那个状态是什么意思?
#4
米小兔2013-04-10 18:50
回复 3楼 azzbcc
R是运行态,W是就绪态,F是完成态
#5
azzbcc2013-04-10 18:55
我先吃饭去啦,目前找到第一个错误
for(i=1;i<=N;i++)
{
  p=new PCB;
  cin>>na;
  cin>>gettime;
  cin>>time;
  strcpy(p->name,na);
  p->cputime=0;
  p->gettime=gettime;
  p->needtime=time;
  if(gettime=0){p->state='W';}
  else {p->state='F';}
  p->round=0;
  if(ready!=NULL)  
   insert(p);
  else
  {
   p->next=ready;  
   ready=p;
  }
  cout<<"输入进程名,到达时间及其需要运行的时间:"<<endl;
}


代码还没理解,可以说说你的思路么?回来再看

[ 本帖最后由 azzbcc 于 2013-4-10 20:12 编辑 ]
#6
azzbcc2013-04-10 19:00
感觉用队列解决简单

额,原来就是队列
#7
米小兔2013-04-10 19:09
回复 5楼 azzbcc
思路就是基于时间片的轮转调度算法,我用手机不太方便打,这个您可以看下我上面举的那个例子。然后我的问题是在状态和时间片占用时间,cpu占用时间,还有随机到达时间,就是不是并发的进程,怎么调度,出问题了,我改了好多次,改不好了,哎,急,
#8
米小兔2013-04-10 19:18
#9
米小兔2013-04-10 19:56
求正解...我头炸了...
#10
米小兔2013-04-10 20:01
有人在看吗? 哇呜呜...
#11
azzbcc2013-04-10 20:02
interrupt()//这个函数是干嘛用的,没看明白
#12
azzbcc2013-04-10 20:05
坦白说,我想重写了,你思路不够清晰

插入应该往哪里插入?

tail竟然毫无用处、、、

而且创建部分不排序,,,

很无奈啊
#13
米小兔2013-04-10 21:38
急...
#14
米小兔2013-04-10 21:40
回复 12楼 azzbcc
不好意思,刚才没刷出来你的回帖,你看这个得怎么写啊?我能力有限,没学好,啊啊啊,急,明天早上要用啊
#15
米小兔2013-04-10 21:45
回复 11楼 azzbcc
那个iterrupt是检查有没有新到达的进程,如果有,就加入就绪队列开始轮转,我是这样想的。
#16
米小兔2013-04-10 21:57
#17
米小兔2013-04-10 22:22
我们那老师自己都不会写程序,还对我们要求这要求那...这代码都让我改疯了,现在都糊涂了
#18
米小兔2013-04-10 22:41
回复 12楼 azzbcc
在重写吗?
#19
azzbcc2013-04-10 22:54
额,要我帮你写?

判断有没有到达是 == ?提前到怎么算?
#20
米小兔2013-04-10 23:03
回复 19楼 azzbcc
我寝室熄灯了,没法写了,明早第一节课交,好痛苦。
判断到达?我的思想是前一个程序刚执行后的CPU占用时间与下一个准备进入就绪队列的进程到达时间相同,然后这个进程就可以进入队列了。
#21
米小兔2013-04-10 23:05
回复 19楼 azzbcc
对哈,那难道是小于等于?
#22
米小兔2013-04-10 23:08
回复 19楼 azzbcc
下一个进程到达时间小于等于前一个刚执行完的CPU占用时间,然后进入队列?这样呢?
#23
米小兔2013-04-10 23:16
回复 19楼 azzbcc
揪心...
#24
azzbcc2013-04-10 23:22
我写吧,count是干嘛的?
int prio;         
int round;         
int cputime;      
int needtime;
int gettime;   
int count;     //?????????   
char state;        
struct node *next
#25
米小兔2013-04-10 23:24
回复 19楼 azzbcc
慢慢写,我明天6点起来看,我是真憋在这了,Thank you,gentle man。
#26
azzbcc2013-04-10 23:49
一会我们也断网了,明天再传吧,感觉用循环链表会容易一些,我试试!
#27
米小兔2013-04-11 04:37
回复 26楼 azzbcc
我今天早上要用
#28
azzbcc2013-04-11 06:03
呵呵,现在来的几步?
#29
azzbcc2013-04-11 06:04
程序代码:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>

typedef struct Data
{
    char name[10];
//    int  prio;  没用到、、、
    int  round;
    int  cputime;
    int  needtime;
    int  gettime;
//    int  count;
    char state;  //添加了一个未到达的状态:'N'
}Data;

typedef struct Node
{
    int data[100];
    int front, rear;
}QueueLink;

int N, need;    //N为进程总数, need为时间片
int Time = 0;    //一共要用的时间
Data all[10];
QueueLink run;

/*
把所有的进程存入all数组,按到达时间排序

队列中存入的是该进程在all数组中对应的下标

再依据时间推进,将已到达的进程入队列,再将未执行完的进程入队列

另外round和cputime分别指什么?他们的值完全一样,或许我理解错了吧
*/

int cmp(const void *a, const void *b)
{
    Data *m = (Data *)a;
    Data *n = (Data *)b;
    return m->gettime - n->gettime;
}

void Output(int time)
{
    int i;
    getchar();
    if (time >= 0)    printf("\n当前时间为:%dms\n", time);

    puts("进程名  到达的时间  占用cpu时间 到完成还要得时间 轮转时间片  状态");
    for (i = 0;i < N;++i)
    {
        printf("  %s         %d             %d            %d             %d        %c\n",
            all[i].name, all[i].gettime, all[i].cputime, all[i].needtime, all[i].round, all[i].state);
    }
    printf("\n");
}

void init()
{
    int i;

    memset(all, 0, sizeof(all));

    printf("输入进程的个数:");
    scanf("%d", &N);

    for (i = 0;i < N;++i)
    {
        puts("输入进程名,到达时间及其需要运行的时间:");
        scanf("%s%d%d", all[i].name, &all[i].gettime, &all[i].needtime);
        Time += all[i].needtime;
        all[i].state = 'N';
    }
    qsort(all, N, sizeof(Data), cmp);

    Output(-1);

    printf("请输入时间片长度:");
    scanf("%d", &need);
    printf("输入时间片长度为: %d\n", need);
}

void DeQueue(int *a)
{    //出队列
    *a = run.data[run.front++];
}

void EnQueue(int a)
{    //入队列
    run.data[run.rear++] = a;
}

void fun()
{
    int i, time = 0, now = 0;
    while (time < Time)
    {
        //将未执行进程入队列
        for (i = 0;i < N;++i)
        {
            if (all[i].gettime <= time && all[i].state == 'N')
            {
                EnQueue(i);
                all[i].state = 'W';
            }
        }
        //将未完成的进程入队列
        for (i = 0;i < run.front;++i)
        {
            if (all[i].state != 'F')
            {
                EnQueue(run.data[i]);
            }
        }
        
        //出队列
        DeQueue(&now);
        if (all[now].state == 'F')
        {    //已经完成进程
            continue;
        }

        all[now].state = 'R';    //将当前设定为运行态
        Output(time);

        if (all[now].needtime > need)
        {
            all[now].needtime -= need;
            all[now].round += need;
            all[now].cputime += need;
            all[now].state = 'W';
            time += need;
        }
        else
        {
            time += all[now].needtime;
            all[now].round += all[now].needtime;
            all[now].cputime += all[now].needtime;
            all[now].needtime = 0;
            all[now].state = 'F';
        }
    }
    Output(time);
}

int main( void )
{
    init();
    fun();
    return 0;
}
#30
米小兔2013-04-11 06:16
回复 29楼 azzbcc
早安,来得及,好给力啊!
#31
米小兔2013-04-11 06:18
回复 29楼 azzbcc
这是C语言?
#32
米小兔2013-04-11 07:41
回复 29楼 azzbcc
怎么错了...呜呜,执行显示不对劲呀
#33
米小兔2013-04-11 07:51
回复 29楼 azzbcc
这程序怎么执行的?我怎么每次执行都有错误,有时间麻烦发下运行截图吧
#34
azzbcc2013-04-11 07:55
昨天好困,用循环链表写得很乱。你是说次序不对么?那个我木时间搞了。。。

有个问题是入队列会有重复,要把continue放到两个循环前面,但是不能动dequeue函数,所以要加一个获取队首函数给now赋值
#35
azzbcc2013-04-11 07:58
我上课了、、12点放学,如果你有时间等的话,我中午把这些问题解决下
#36
米小兔2013-04-11 08:09
回复 35楼 azzbcc
好的
#37
米小兔2013-04-11 08:33
回复 35楼 azzbcc
中午的时候你执行一下,然后截图给我看下,看下你是怎么执行的
#38
azzbcc2013-04-11 10:20
输入进程的个数:4
输入进程名,到达时间及其需要运行的时间:
a 0 5
输入进程名,到达时间及其需要运行的时间:
b 1 3
输入进程名,到达时间及其需要运行的时间:
c 2 1
输入进程名,到达时间及其需要运行的时间:
d 3 6
进程名  到达的时间  占用cpu时间 到完成还要得时间 轮转时间片  状态
  a         0             0            5             0        N
  b         1             0            3             0        N
  c         2             0            1             0        N
  d         3             0            6             0        N

请输入时间片长度:2
输入时间片长度为: 2

当前时间为:0ms
进程名  到达的时间  占用cpu时间 到完成还要得时间 轮转时间片  状态
  a         0             0            5             0        R
  b         1             0            3             0        N
  c         2             0            1             0        N
  d         3             0            6             0        N



当前时间为:2ms
进程名  到达的时间  占用cpu时间 到完成还要得时间 轮转时间片  状态
  a         0             2            3             2        W
  b         1             0            3             0        R
  c         2             0            1             0        W
  d         3             0            6             0        N



当前时间为:4ms
进程名  到达的时间  占用cpu时间 到完成还要得时间 轮转时间片  状态
  a         0             2            3             2        W
  b         1             2            1             2        W
  c         2             0            1             0        R
  d         3             0            6             0        W



当前时间为:5ms
进程名  到达的时间  占用cpu时间 到完成还要得时间 轮转时间片  状态
  a         0             2            3             2        R
  b         1             2            1             2        W
  c         2             1            0             1        F
  d         3             0            6             0        W



当前时间为:7ms
进程名  到达的时间  占用cpu时间 到完成还要得时间 轮转时间片  状态
  a         0             4            1             4        W
  b         1             2            1             2        W
  c         2             1            0             1        F
  d         3             0            6             0        R



当前时间为:9ms
进程名  到达的时间  占用cpu时间 到完成还要得时间 轮转时间片  状态
  a         0             4            1             4        R
  b         1             2            1             2        W
  c         2             1            0             1        F
  d         3             2            4             2        W



当前时间为:10ms
进程名  到达的时间  占用cpu时间 到完成还要得时间 轮转时间片  状态
  a         0             5            0             5        F
  b         1             2            1             2        R
  c         2             1            0             1        F
  d         3             2            4             2        W



当前时间为:11ms
进程名  到达的时间  占用cpu时间 到完成还要得时间 轮转时间片  状态
  a         0             5            0             5        F
  b         1             3            0             3        F
  c         2             1            0             1        F
  d         3             2            4             2        R



当前时间为:13ms
进程名  到达的时间  占用cpu时间 到完成还要得时间 轮转时间片  状态
  a         0             5            0             5        F
  b         1             3            0             3        F
  c         2             1            0             1        F
  d         3             4            2             4        R



当前时间为:15ms
进程名  到达的时间  占用cpu时间 到完成还要得时间 轮转时间片  状态
  a         0             5            0             5        F
  b         1             3            0             3        F
  c         2             1            0             1        F
  d         3             6            0             6        F
#39
米小兔2013-04-11 10:45
回复 38楼 azzbcc
啊?为什么我执行的结果和上面不一样啊,代码一样吗?
#40
米小兔2013-04-11 10:48
回复 38楼 azzbcc
我就是这样输入的,可是不行啊
#41
yinfanghappy2013-07-01 11:23
这个很像操作系统的实验报告的实验题,时间片轮转法
#42
不玩虚的2013-09-10 13:54
哈哈操作系统调度,好在我以前写过,话说问题解决了没?
1