精华内容
下载资源
问答
  • 学无止境环境线程的时间片分配线程的执行进程的状态三个...对于有子进程的程序来说,进程刚被其父进程fork出来,是平分其父进程的剩余时间片的。这个时间片执行完后,就会根据它的初始优先级来重新分配时间片 l

    环境

    无特殊指明,本文基于linux

    线程的时间片分配

    1. 对linux系统来说,用户创建进程后,CPU分配时间片的单位其实是按线程分的。假如你的程序里没有创建线程,你可以把它看成是一个单线程程序,Linux内核其实不区分进程和线程,内核把执行单元叫做任务(task)。线程则是最小的工作单元。对于有子进程的程序来说,当该进程刚被其父进程fork出来时,是平分其父进程的剩余时间片的。这个时间片执行完后,就会根据它的初始优先级来重新分配时间片
    2. linux的时间片不能直接修改,可以通过修改进程的优先级来间接修改。调度程序会根据优先级动态调整时间片。可以通过系统调用(终端命令行输入)nice()来修改进程优先级,从而影响时间片。nice的取值范围是-20到+19,-20优先级最高,+19最低。
      注意:只有超级用户才能在调用它时使用负值。
    3. 根据优先级不同分得到的时间片长度不同,优先级为+19时最低,只分配最小时间片5ms,优先级为0时是100ms,优先级是-20时是最大时间片800ms。
      注意:具体时间数字根据实际内核配置有差异
    4. 线程被创建好会被加入到内核的线程队列中等待执行,每个线程执行自己所分配的时间片长度后切换上下文,执行下一个线程。如期间线程优先级变化,还会从新分配时间片长度。

    线程优先级

    1-99:实时优先级;
    100-139:静态优先级;
    数字越小,优先级越高;
    Nice值:
    (-20,19)对应(100,139)
    可通过nice值调整的优先级范围:100-139
    分别对应于:-20, 19
    进程启动时,其nice值默认为0,其优先级是120;

    线程的执行

    1. 多线程的一种用途就是能同时做好几件事情,以提高效率。但实际问题是,CPU的数量(核心数,下同)是有限的,而且并不多。如果你的CPU有8个CPU,并且整个系统中有8个线程的话,不考虑中断等因素,每个线程理论上能一直执行下去。

    2. 然而多于8个线程以后,操作系统就必须进行调度,也就是分配时间片。具体的分配方案,或者说调度算法有很多种。调度算法需要考虑和优化的问题。比如线程和进程有优先级,在抢占式的调度中,优先级高的线程可以从优先级低的线程那里抢占CPU。

    3. 另外,在多CPU平台上,调度算法还要考虑缓存的关联性等。如果一个进程创建了很多线程的话,最多也只有8个能够处于执行的状态,其余的线程必须等待调度。线程被调度的时候需要进行上下文切换,这个操作是一种额外的开销。线程数量过多的时候,上下文切换产生的额外开销会对系统的效率造成负面影响。

    进程的状态

    也可以是说是线程在运行时的状态

    三个状态

    1. 运行(running)态:进程占有处理器正在运行。
    2. 就绪(ready)态:进程具备运行条件,等待系统分配处理器以便运行。
    3. 等待(wait)态:又称为阻塞(blocked)态或睡眠(sleep)态,指进程不具备运行条件,正在等待某个事件的完成。

    通常,一个进程在创建后将处于就绪状态。每个进程在执行过程中,任意时刻当且仅当处于上述三种状态之一。

    状态的迁移

    1. 运行态 > 等待态:等待使用资源或某事件发生,如等待外设传输等
    2. 等待态 > 就绪态:资源得到满足或某事件己经发生,如外设传输结束,睡眠时间结束
    3. 运行态 > 就绪态:运行时间片到,或出现有更高优先权进程(如windows的抢占时算法)。
    4. 就绪态 > 运行态:CPU空闲时被调度选中一个就绪进程执行。

    进程标识符

    pid_t pid; 进程标识符

    pid_t tgid; 线程组标识符(thread group id)

    其中pid表示进程标识符,在默认情况下,PID的取值范围是0~32767,即系统内进程最多有32767个。tgid表示的是线程组标识符,在内核运行多进程/多线程任务时,对于一个进程内的不同线程来说,每个线程都有不同的pid,但是有统一的tgid,线程组的领头线程的pid与tgid相同。当我们使用getpid()函数获取当前运行进程的进程号时,实际getpid()函数的返回值是tgid的值而不是pid的值。

    内核调度

    参考网址

    https://www.ibm.com/developerworks/cn/linux/l-cn-scheduler/index.html

    展开全文
  • 当执行时间片用完时,由一个计时器发出时钟中断请求,调度程序便据此信号来停止该进程执行,并将它送往就绪队列的末尾;然后,再把处理机分配给就绪队列中新的队首进程,同时也让它执行一个时间片。这样就可以...

    一 定义

    时间片轮转算法是将所有的就绪进程按先来先服务的原则,排成一个队列,按时间片轮转。时间片的大小从几ms到几百ms。当执行的时间片用完时,由一个计时器发出时钟中断请求,调度程序便据此信号来停止该进程的执行,并将它送往就绪队列的末尾;然后,再把处理机分配给就绪队列中新的队首进程,同时也让它执行一个时间片。这样就可以保证就绪队列中的所有进程,在一给定的时间内,均能获得一时间片的处理机执行时间。


    二 代码

    进程类如下:

    import java.util.Iterator;
    import java.util.Scanner;
    import java.util.TreeSet;
    
    public class Process implements Comparable<Process>{                        
        private String ProcessName;             //进程名
        private int ReachTime;                  //到达时间
        private int ProcessTime;                //处理时间
        private int FinishTime;                 //完成时间
        private int PeriodTime;                 //周转时间
        private int StartTime;                  //开始时间
        private double WeightedPeriodTime;      //带权周转时间
        private int Priority;                   //优先级
    
        public Process(String processname,int reachTime, int processTime) {
            super();
            ProcessName = processname;
            ReachTime = reachTime;
            ProcessTime = processTime;
        }
    
        public Process(String processName, int reachTime, int processTime, int priority) {
            super();
            ProcessName = processName;
            ReachTime = reachTime;
            ProcessTime = processTime;
            Priority = priority;
        }
    
        public int getPriority() {
            return Priority;
        }
    
        public String getProcessName() {
            return ProcessName;
        }
    
        public int getReachTime() {
            return ReachTime;
        }
    
        public int getProcessTime() {
            return ProcessTime;
        }
    
        public int getFinishTime() {
            return FinishTime;
        }
    
        public int getPeriodTime() {
            return PeriodTime;
        }
    
        public void setProcessTime(int processTime) {
            ProcessTime = processTime;
        }
    
        public void setFinishTime(int finishTime) {
            FinishTime = finishTime;
        }
    
        public void setPeriodTime(int periodTime) {
            PeriodTime = periodTime;
        }
    
        public int getStartTime() {
            return StartTime;
        }
    
        public void setStartTime(int startTime) {
            StartTime = startTime;
        }
    
        public double getWeightedPeriodTime() {
            return WeightedPeriodTime;
        }
    
        public void setWeightedPeriodTime(double weightedPeriodTime) {
            WeightedPeriodTime = weightedPeriodTime;
        }
    
        @Override
        public int compareTo(Process o) {
            // TODO Auto-generated method stub
            if ( this.ReachTime > o.ReachTime)
                return 1;
            else if ( this.ReachTime < o.ReachTime)
                return -1;
            return 0;
        }
    
        @Override
        public int hashCode() {
            final int prime = 31;
            int result = 1;
            result = prime * result + ReachTime;
            return result;
        }
    
        public void Print(){
            System.out.print(this.ProcessName+" "+this.ReachTime+"  "+this.ProcessTime+"    "+" "+this.StartTime+"  "+this.FinishTime+" "+this.PeriodTime+" ");
            System.out.printf("%.4f",this.WeightedPeriodTime);
            System.out.println();
        }
    }

    时间片轮转算法实现如下:

    import java.util.Collection;
    import java.util.Iterator;
    import java.util.LinkedList;
    import java.util.Scanner;
    import java.util.TreeSet;
    
    public class RR {
        private TreeSet<Process> process = new TreeSet<Process>();
    
        public RR() {
            System.out.println("请输入要添加的进程数:");
            Scanner in = new Scanner(System.in);
            int Num = in.nextInt();
            System.out.println("开始初始化进程信息(进程名 到达时间 耗时):");
            for ( int i = 0 ; i < Num ; i++){
                String processname = in.next();
                int reachtime = in.nextInt();
                int processtime = in.nextInt();
                Process p = new Process(processname,reachtime, processtime); 
                process.add(p);
            }
        }
    
        public TreeSet<Process> getProcess() {
            return process;
        }
    
        public void CarryOut_RR(int Timeperiod){
            LinkedList<Process> Tmp = new LinkedList<>();
            LinkedList<Process> ProcessSeries = new LinkedList<Process>();
            LinkedList<Process> FinsishProcess = new LinkedList<Process>();
            LinkedList<Integer> processtime = new LinkedList<Integer>();
            Iterator<Process> it = this.process.iterator();
            while(it.hasNext()){
                Process p = it.next();
                Tmp.add(p);
                processtime.add(p.getProcessTime());
            }
            int NowTime = Tmp.peekFirst().getReachTime();                       //当前时间
            int NowProcessTime = processtime.pop();
            //第一个进程特殊情况
            Process p = Tmp.pop();
            p.setStartTime(NowTime);
            p.setFinishTime(p.getFinishTime()+Timeperiod);
            p.setPeriodTime(p.getFinishTime() - p.getReachTime());
            p.setWeightedPeriodTime(p.getPeriodTime() * 1.0 / p.getProcessTime());
            NowTime += Timeperiod;
            int FinishTime = p.getFinishTime();                                 //完成时间
            NowProcessTime -= Timeperiod;
            if ( NowProcessTime > 0){
                ProcessSeries.add(p);
                processtime.add(NowProcessTime);
            }else{
                if ( NowProcessTime < 0){
                    p.setFinishTime(p.getFinishTime() + NowProcessTime);
                    p.setPeriodTime(p.getFinishTime() - p.getReachTime());
                    p.setWeightedPeriodTime(p.getPeriodTime() * 1.0 / p.getProcessTime());
                    NowTime += NowProcessTime;
                    FinishTime = p.getFinishTime();
                }
                FinsishProcess.add(p);
            }
            //时间轮转法
            int len = this.process.size() - 1;
            for ( int i = 0 ; i < len ; i++){
                p = Tmp.pop();
                NowProcessTime = processtime.pop();
                if ( NowTime >= p.getReachTime())
                p.setStartTime(NowTime);
                p.setFinishTime(Timeperiod + FinishTime);
                p.setPeriodTime(p.getFinishTime() - p.getReachTime());
                p.setWeightedPeriodTime(p.getPeriodTime() * 1.0 / p.getProcessTime());
                FinishTime = p.getFinishTime();
                NowTime += Timeperiod;
                NowProcessTime -= Timeperiod;
                if ( NowProcessTime > 0){
                    ProcessSeries.add(p);
                    processtime.add(NowProcessTime);
                }else{
                    if ( NowProcessTime < 0){
                        p.setFinishTime(p.getFinishTime() + NowProcessTime);
                        p.setPeriodTime(p.getFinishTime() - p.getReachTime());
                        p.setWeightedPeriodTime(p.getPeriodTime() * 1.0 / p.getProcessTime());
                        NowTime += NowProcessTime;
                        FinishTime = p.getFinishTime();
                    }
                    FinsishProcess.add(p);
                }
            }
            while ( !processtime.isEmpty()){
                p = ProcessSeries.pop();
                NowProcessTime = processtime.pop();
                p.setFinishTime(Timeperiod + FinishTime);
                p.setPeriodTime(p.getFinishTime() - p.getReachTime());
                p.setWeightedPeriodTime(p.getPeriodTime() * 1.0 / p.getProcessTime());
                FinishTime = p.getFinishTime();
                NowProcessTime -= Timeperiod;
                if ( NowProcessTime > 0){
                    ProcessSeries.add(p);
                    processtime.add(NowProcessTime);
                }else{
                    if ( NowProcessTime < 0){
                        p.setFinishTime(p.getFinishTime() + NowProcessTime);
                        p.setPeriodTime(p.getFinishTime() - p.getReachTime());
                        p.setWeightedPeriodTime(p.getPeriodTime() * 1.0 / p.getProcessTime());
                        FinishTime = p.getFinishTime();
                    }
                    FinsishProcess.add(p);
                }
            }
    
            this.Print(FinsishProcess);
            System.out.printf("平均周转时间:%.4f",this.Avg_ProcessTime(FinsishProcess));
            System.out.println();
            System.out.printf("平均带权周转时间:%.4f",this.Avg_WeightedProcessTime(FinsishProcess));
            System.out.println();
        }
    
        public double Avg_ProcessTime(Collection<Process> FinsishProcess){                      //平均周转时间
            double avg = 0;
            Iterator<Process> it = this.process.iterator();
            while( it.hasNext()){
                Process p = it.next();
                avg += p.getPeriodTime();
            }
            avg /= this.process.size();
            return avg;
        }
    
        public double Avg_WeightedProcessTime(Collection<Process> FinsishProcess){                      //平均带权周转时间
            double avg = 0;
            Iterator<Process> it = this.process.iterator();
            while( it.hasNext()){
                Process p = it.next();
                avg += p.getWeightedPeriodTime();
            }
            avg /= this.process.size();
            return avg;
        }
    
        public void Print(Collection<Process> FinsishProcess){
            System.out.println("            调度示意图");
            System.out.println("进程  到达时间    耗时  开始时间    完成时间    周转时间    带权周转时间");
            Iterator<Process> it = FinsishProcess.iterator();
            while( it.hasNext()){
                Process p = it.next();
                p.Print();
            }
        }
    
        public static void main(String[] args) {
            // TODO Auto-generated method stub
            RR rr = new RR();
            rr.Print(rr.getProcess());
            System.out.println("请输入时间片:");
            Scanner in = new Scanner(System.in);
            int Timeperiod = in.nextInt();                                      //时间片
            rr.CarryOut_RR(Timeperiod);
            in.close();
        }
    
    }
    
    展开全文
  • 进程调度之时间片轮转调度算法(实验三)

    万次阅读 多人点赞 2016-11-05 20:53:50
    在分系统中,最简单最常用的就是基于时间片轮转调度算法,时间片轮转调度算法是非常公平的处理机分配方式,让就绪队列的每个进程每次仅运行一个时间片。 1.时间片轮转调度算法的基本原理  在时间片轮转调度算法中...

    在分时系统中,最简单最常用的就是基于时间片轮转调度算法,时间片轮转调度算法是非常公平的处理机分配方式,让就绪队列的每个进程每次仅运行一个时间片。

    1.时间片轮转调度算法的基本原理

       在时间片轮转调度算法中,系统根据先来先服务的原则,将所有的就绪进程排成一个就绪队列,并且每隔一段时间产生一次中断,激活系统中的进程调度程序,完成一次处理机调度,把处理机分配给就绪队列队首进程,让其执行指令。当时间片结束或进程执行结束,系统再次将cpu分配给队首进程。

    2.进程切换时机

          时间片尚未结束,进程已经执行结束,立即激活调度程序,将其从就绪队列中删除,在调度就绪队列的队首进程执行,开启新的时间片(计数器置0)。

        时间片已经结束,进程尚未结束,立即激活进程调度程序,未执行完的进程放到就绪队列的队尾。

    3.时间片大小的确定

       在轮转调度算法中时间片的大小对系统的性能有很大的影响。若时间片很小,将有利于短作业,其能够在这个时间片内完成。时间片过小意味着会进行频繁的进程切换,这将增大系统的开销。若时间片选择太长,时间片轮转调度算法将退化为先来先服务的进程调度算法。


    时间片轮转调度算法的C语言模拟

    #include <stdio.h>
    #include <string.h>
    #include <stdlib.h>
    //#define OUTALLINFO //若要输出详细的进程描述信息则打开宏
    #define Max 256
    #define time 2 //时间片大小
    
    enum pathread_attr{ //进程的状态信息
        runing = 1,
        wait,
        finsih
    };
    
    struct Pthread{ //描述进程信息
      char *name;
      int come_time;
      int need_time;
      int runing_time;
      double zz_time;
      double dqzz_time;
      enum pathread_attr attr;
      struct Pthread *next;
    
      Pthread() //默认构造函数
      {
          name = NULL;
          come_time = 0;
          runing_time  = need_time = 0;
          zz_time = 0;
          dqzz_time = 12.66;
          attr = wait;
          next = NULL;
      }
    
      void get_info(int end_time) //计算周转时间,带权周转时间
      {
    
    #ifndef OUTALLINFO
         printf("pathread:%s over time:%d\n",name,end_time);
    #endif // OUTALLINFO
    
         this->zz_time = (end_time - this->come_time) * 1.0;
         dqzz_time = zz_time / need_time;
      }
    
      void copy_queue(struct Pthread *temp) //拷贝进程信息
      {
          name = (char*)malloc(sizeof(char) * strlen(temp->name));
          strcpy(name,temp->name);
    
          come_time = temp->come_time;
          need_time = temp->need_time;
          runing_time = temp->runing_time;
          attr = temp->attr;
      }
    
    };
    
    int run_sum = 0; //统计进程的个数
    
    void init_pthread(struct Pthread *head,const char *name,const int come_time,const int need_time) //初始化进程信息
    {
        struct Pthread *temp = new Pthread();
        temp->name = (char *) malloc(sizeof(char) * strlen(name));
        strcpy(temp->name,name);
        temp->come_time = come_time;
        temp->need_time = need_time;
        temp->runing_time = need_time;
        temp->attr = wait;
    
        temp->next = head->next;
        head ->next = temp;
    
        return;
    }
    
    void out_one(struct Pthread *temp) //输出一个进程信息
    {
    
    
    #ifdef OUTALLINFO
        printf("%s pathread info:\n",temp->name);
        printf("come_time: %d\n",temp ->come_time);
        printf("need_time: %d\n",temp ->need_time);
        switch(temp->attr){
            case 1: printf("attr: waiting \n"); break;
            case 2: printf("attr: runing \n"); break;
            case 3: printf("attr: finsih \n"); break;
        }
    #endif // OUTALLINFO
    
    
        printf("周转时间: %0.2f\n",temp->zz_time);
        printf("带权周转时间: %0.2f\n",temp->dqzz_time);
    
        return;
    }
    
    void out_all(struct Pthread *head) //输出所有进程信息
    {
        for(struct Pthread *p = head->next; p; p = p->next)
            out_one(p);
    
        return;
    }
    
    void add_queue(struct Pthread *head_temp,struct Pthread *head_queue) //添加进程到就绪队列
    {
        struct Pthread *temp = new Pthread();
        temp->copy_queue(head_temp);
    
        if(!head_queue->next)
            temp->attr = runing;
        else
            temp->attr = wait;
    
        struct Pthread *p = NULL;
        for(p = head_queue; p ->next; p = p->next);
        p->next = temp;
    
        return;
    }
    
    void queue_del(struct Pthread *head_queue) //从就绪队列删除一个进程
    {
        if(!(head_queue ->next))
            return;
    
        head_queue ->next->attr = finsih;
        out_one(head_queue ->next);
    
        struct Pthread *p = head_queue ->next;
    
        head_queue->next = p->next;
        delete p;
    
        return;
    }
    
    void sqrt_queue(struct Pthread *head_queue) //将时间片结束还未完成的进程放到队尾
    {
        struct Pthread *p = head_queue->next;
        head_queue->next = p->next;
        p->next = NULL;
    
        struct Pthread *q = NULL;
    
        for(q = head_queue; q ->next; q = q->next);
        q ->next = p;
    
        return;
    }
    
    void mo_ni(struct Pthread *head,struct Pthread *head_queue) //模拟时间片轮转调度算法
    {
        int run_i = 0,run_over = 0,time_runing = 0;
    
        while(time_runing >= 0){
            for(struct Pthread *p = head ->next; p; p = p->next) //检查此时刻是否有进程到达
            if(time_runing == p->come_time)
                add_queue(p,head_queue);
    
            if(head_queue ->next){ //如果就绪队列非空
                if(run_i == time && head_queue->next->runing_time){ //时间片结束&&进程未完成
                        sqrt_queue(head_queue); //把进程放到就绪队列队尾
                        run_i = 0; //时间片置0
                }
                if(!head_queue->next->runing_time){ //如果进程执行结束
                        head_queue->next->get_info(time_runing);
                        queue_del(head_queue); //从就绪队列中删除该进程
                        run_i = 0; //时间片置0
                        run_over++; //统计已经结束的进程个数
                }
               if(head_queue ->next) //如果有进程正在执行,服务时间减1
                head_queue->next->runing_time--;
                run_i++; //时间片加1
            }
    
            time_runing++;
    
            if(run_over == run_sum) //如果处理完所有进程则结束模拟
                return;
        }
    
        return;
    }
    
    int main(int argc,char *argv[])
    {
        struct Pthread *head = new Pthread(); //进程链表
        struct Pthread *head_queue = new Pthread(); //就绪态进程链表队列
        char name[Max];
        int come_time,need_time;
        FILE *input_file = fopen("C:\\Users\\chenhongyu\\Desktop\\test.txt","r"); //读取测试信息
    
        printf("plase input name come_time need_time priority,if over,plase input [Ctrl + Z]\n\n");
        while(fscanf(input_file,"%s%d%d",name,&come_time,&need_time) != EOF){
            init_pthread(head,name,come_time,need_time); //初始化进程链表
            run_sum++; //统计总共有多少个进程
        }
    
        mo_ni(head,head_queue); //模拟时间片轮转调度算法
    
        return 0;
    }
    
    


    展开全文
  • ** 1.算法原理 ** 时间片轮转调度算法 a.在时间片轮转调度算法中...当时间片结束或进程执行结束,系统再次将cpu分配给队首进程。 b.时间片尚未结束,进程已经执行结束,立即激活调度程序,将其从就绪队列中删除,在...

    **

    1.算法原理

    **
    时间片轮转调度算法

    1. a.在时间片轮转调度算法中,系统根据先来先服务的原则,将所有的就绪进程排成一个就绪队列,并且每隔一段时间产生一次中断,激活系统中的进程调度程序,完成一次处理机调度,把处理机分配给就绪队列队首进程,让其执行指令。当时间片结束或进程执行结束,系统再次将cpu分配给队首进程。
    2. b.时间片尚未结束,进程已经执行结束,立即激活调度程序,将其从就绪队列中删除,在调度就绪队列的队首进程执行,开启新的时间片(计数器置0)。时间片已经结束,进程尚未结束,立即激活进程调度程序,未执行完的进程放到就绪队列的队尾。
    3. c.在轮转调度算法中时间片的大小对系统的性能有很大的影响。若时间片很小,将有利于短作业,其能够在这个时间片内完成。时间片过小意味着会进行频繁的进程切换,这将增大系统的开销。若时间片选择太长,时间片轮转调度算法将退化为先来先服务的进程调度算法。

    优先权调度算法

    1. a.N进程采用动态优先权算法的进程调度;
    2. b.每个用来标识进程的进程控制块PCB用结构描述,包括以下字段:进程标识数ID,进程优先数PRIORITY,进程以占用的CPU时间CPUTIME,进程还需占用的CPU时间ALLTIME,进程状态STATE等。
    3. c.优先数改变的原则:进程在就绪队列中呆一个时间片,优先数增加1,进程每运行一个时间片优先数减3。
    4. d.设置调度前的初始状态。
    5. e.将每个时间片内的进程情况显示出来

    c语言实现

    //时间片轮转法
    #include<stdio.h>
    #include<stdlib.h>
    #include<iostream>
    using namespace std;
    struct Node {
    	char name;
    	int Tarrive;//到达时间
    	int Tservice;//服务时间
    	int Tsurplus;//剩余时间
    	int Tstart;//开始时间
    	int Taccomplish;//完成时间
    	int prio;//优先级---数字越大优先级越高
    	int if_finish;//进程是否完成
    	int num;//进程个数
    }job[10];
    //按到达时间排序
    void Arrive_sort(int num)
    {
    	int temp1, temp2, temp3;
    	for (int i = 0; i < num; i++)
    	{
    		for (int j = i + 1; j < num; j++)
    		{
    			if (job[i].Tarrive > job[j].Tarrive)
    			{
    				temp1 = job[j].name;
    				job[j].name = job[i].name;
    				job[i].name = temp1;
    				temp2 = job[j].Tarrive;
    				job[j].Tarrive = job[i].Tarrive;
    				job[i].Tarrive = temp2;
    				temp3 = job[j].Tservice;
    				job[j].Tservice = job[i].Tservice;
    				job[i].Tservice = temp3;
    			}
    		}
    	}
    }
    
    void RR(int num)//RR算法
    {
    	int q;
    	cout << "请输入时间片长度:" << endl;
    	cin >> q;
    	int flag = 1;//标志队列中是否还有进程
    	int finish_pro = 0;//完成的进程数
    	cout << "进程名称\t" << "开始时间\t" << "运行时间\t" << "剩余服务时间\t" << "结束时间\t" << endl;
    	int time;//记录当前时刻时间
    	int c = 0;
    	while (finish_pro < num)
    	{
    		flag = 0;//就绪队列里没进程
    		for (int i = c; i < num; i++)
    		{
    			Arrive_sort(num);
    			job[i].Tsurplus = job[i].Tservice;
    			job[i].Tstart = job[i - 1].Taccomplish;//上一个作业结束时间
    			if (job[i].Tstart < job[i].Tarrive)//该作业的开始时间小于到达时间
    			{
    				job[i].Tstart = job[i].Tarrive;
    			}
    			else
    			{
    				job[i].Tstart = job[i - 1].Taccomplish;
    			}
    			time = job[i].Tstart;
    			if (job[i].if_finish == 1) continue;//该进程已完成
    			else
    			{
    				if (job[i].Tsurplus <= q && time >= job[i].Tarrive)//未完成且少于一个时间片
    				{
    					flag = 1;
    					time = time + job[i].Tsurplus;
    					job[i].if_finish = 1;//该进程完成
    					job[i].Taccomplish = time;
    					cout  << job[i].name << "\t\t" << job[i].Taccomplish - job[i].Tsurplus << "\t\t" << job[i].Tsurplus << "\t\t" << 0 << "\t\t" << job[i].Taccomplish << endl;
    					job[i].Tsurplus = 0;
    				}
    				else if (job[i].Tsurplus > q && time >= job[i].Tarrive)
    				{
    					flag = 1;
    					time = time + q;
    					job[i].Tsurplus -= q;
    					job[i].Taccomplish = time;
    					cout << job[i].name << "\t\t" << time - q << "\t\t" << q << "\t\t" << job[i].Tsurplus << "\t\t" << job[i].Taccomplish << endl;
    					job[num].name = job[i].name;
    					job[num].Tarrive = time;
    					job[num].Tservice = job[i].Tsurplus;
    					num++;
    				}
    				if (job[i].if_finish == 1) finish_pro++;//一个进程完成加一
    			}
    			c++;
    		}break;
    		if (flag == 0 && finish_pro < num)//没执行完且没进入就绪队列
    		{
    			for (int i = 0; i < num; i++)
    			{
    				if (job[i].if_finish == 0)
    				{
    					time = job[i].Tarrive;
    					break;
    				}
    			}
    		}
    	}	
    }
    //输出
    void print(int num)
    {
    	cout << "进程名" << "\t" << "到达时间" << "\t" << "服务时间" << "\t" << "完成时间" << endl;
     
    	for (int i = 0; i < num; i++)
    	{
    		cout << job[i].name << "\t" << job[i].Tarrive << "\t\t" << job[i].Tservice << "\t\t" << job[i].Taccomplish << endl;
    	}
    }
    void display(int num)
    {
    		
    			RR(num);
    }
    int main()
    {
    	int num;
    	char jname;
    	int arrive;
    	int service;
    	int accomplish;
    	cout << "请输入进程个数:" << endl;
    	cin >> num;
    	for (int i = 0; i < num; i++)
    	{
    		cout << "请输入进程名、到达时间、服务时间" << endl;
    		cin >> jname;
    		job[i].name = jname;
    		cin >> arrive;
    		job[i].Tarrive = arrive;
    		cin >> service;
    		job[i].Tservice = service;
    	}
    	display(num);
    	return 0;
    }
    //动态优先级算法
    #include<stdio.h>
    #include<stdlib.h>
    
    typedef struct PCB{
        int PID;
        char state;
        int priority;
        int runTime;
        int workTime;
        struct PCB *next;
    }*process,ptr;
    
    PCB *ready=NULL,*p;
    int num;
    
    void PCBsort(){
        PCB *first,*second;
        int flag=0;
        if((ready==NULL)||((p->priority)<(ready->priority))){
            p->next=ready;
            ready = p;
        }else{
            first=ready;
            second=first->next;
            while(second!=NULL){
                if((p->priority)<(second->priority)){
                    p->next=second;
                    first->next=p;
                    second=NULL;
                    flag=1;
                }else{
                    first=first->next;
                    second=second->next;
                }
            }
            if(flag==0)first->next=p;
        }
    }
    
    void inputProcess()
    {
        int i;
        printf("输入%d个进程的信息(PID、优先级、运行时间)\n",num);
        for(i=0;i<num;i++){
            p=(PCB*)malloc(sizeof(PCB));
            scanf("%d %d %d",&p->PID,&p->priority,&p->runTime);
            p->workTime=0;
            p->state='w';
            p->next=NULL;
            PCBsort();
        }
    }
    
    int space()
    {
        int k=0;
        PCB* pr=ready;
        while(pr!=NULL){
            k++;
            pr=pr->next;
        }
        return k;
    }
    
    void showInfo(ptr *pr){
        printf("\nPID\t状态\t优先级\t运行时间\t剩余时间\n");
        printf("————————————————————————————\n");
        printf(" %d\t",pr->PID);
        printf(" %c\t",pr->state);
        printf("%d\t",pr->priority);
        printf("%d\t\t",pr->runTime);
        printf("%d\t",pr->runTime-pr->workTime);
        printf("\n");
    }
    
    void priorityRun()
    {
        int len,h=0;
        char ch;
        inputProcess();
        len=space();
        while((len!=0)&&(ready!=NULL))
        {
            ch=getchar();
            h++;
            printf("\n 运行次数:%d \n",h);
            p=ready;
            ready=p->next;
            p->next=NULL;
            p->state='R';
            PCB* pr;
            showInfo(p);
            pr=ready;
            while(pr!=NULL){
                showInfo(pr);
                pr=pr->next;
            }
            (p->workTime)++;
            if(p->workTime==p->runTime){
                printf("\n 进程%d 已结束。\n",p->PID);
                free(p);
            }
            else{
                (p->priority)++;
                p->state='w';
                PCBsort();
            }
            printf("\n 按任一键继续 ......");
        }
        printf("\n\n 进程已经完成 .\n");
        ch=getchar();
    }
    
    int main()
    {
        printf("—————————————————优先级调度算法—————————————————\n");
        printf("输入进程数目:");
        scanf("%d",&num);
        priorityRun();
    }
    
    

    在这里插入图片描述
    在这里插入图片描述

    展开全文
  • 【操作系统 - 2】时间片轮转RR进程调度算法

    万次阅读 多人点赞 2017-03-17 23:56:31
    【操作系统 - 2】时间片轮转RR进程调度算法。学习至此,发现很多学了但很久没用的知识,久而久之,慢慢遗忘。等哪天还需要的话,却发现已经忘得差不多了,即使整理了文档(word等),还是得从头再学一遍。读研第一...
  • python实现进程时间片轮转算法

    千次阅读 2018-11-26 21:24:47
    python实现的时间片轮转算法,在代码优化上还需要提升 import random def createP(p_num): """ 创建字典,根据输入的进程数进行创建进程字典,时间为随机1-9s之间 """ p_dict ...
  • 线程,进程,CPU时间片

    千次阅读 2019-09-18 13:21:17
    CPU时间片是直接分配给线程的,线程拿到CPU时间片就能执行了 CPU时间片不是先分给进程然后再由进程分给进程下的线程的。 所有的进程并行,线程并行都是看起来是并行,其实都是CPU片轮换使用。 线程分到了CPU时间片,...
  • "进程%s的时间片用完\n" ,run->next->name); run->next->t = 0 ; if (run->next->next != NULL ) { r->next = run->next; run->next = run->next->next; r = r->next; r->next = NULL ; if (run->next->...
  • 进程调度:时间片轮转调度算法

    万次阅读 2016-11-24 14:43:19
    (4) 掌握时间片轮转法进程调度算法 二、实验原理 (1)建立进程控制块 (2)设计两个链队列,分别表示就绪队列和完成队列 (3)用户输入进程标识符,进程到达时间,进程所需的时间,申请空间存放进程,PCB...
  • 进程调度算法 —— 时间片轮转调度

    千次阅读 2018-11-03 13:20:53
    /*时间片轮转调度算法*/ #include&lt;stdio.h&gt; #define MAX 50 struct a_struct { char name[10]; //进程名字 int number; //进程编号 float dt; //到达时间 float begin_time; //开始运行时间 ...
  • 时间片轮转调度算法详细判断流程: 例题: 进程 到达时间 服务时间 P1 0.0 7 P2 2.0 4 P3 4.0 1 P4 5.0 4 时间片为1 先放出来最终的结果 ↑ ↑ ↑ ↑ ↑ ...
  • 时间片轮转调度算法的提及和关于fork函数执行父,子进程先后顺序的理解  fork函数是用来创建进程的,命令行下输入man2 fork 看到他的函数声明: #include  pid_t fork(void);  fork函数调用一次会返回两次值...
  • 【操作系统】时间片轮转调度法

    千次阅读 2020-12-21 10:40:02
    每个进程被分配一时间段,称作它的时间片,即该进程允许运行的时间。 中文名 时间片轮转调度算法 释义 每个进程被分配一时间段 定义 该进程允许运行的时间 合理时间 时间片设为100毫秒 时间...
  • 操作系统:时间片轮转RR进程调度算法

    千次阅读 多人点赞 2018-12-09 22:26:24
    时间片轮转RR进程调度算法:用于分系统中的进程调度。每次调度,总是选择就绪队列的队首进程,让其在CPU上运行一个系统预先设置好的时间片。一个时间片内没有完成运行的进程,返回到绪队列末尾重新排队,等待下...
  • 模拟短作业优先算法、时间片轮转算法(RR)和优先数算法的执行情况,并 动态画出其进程执行的 Gantt 图,计算以上算法的每个进程的响应时间和周转时间。 /* 模拟短作业优先算法、时间片轮转算法(RR)和优先数算法的...
  • 进程调度-时间片轮转C语言源代码

    千次阅读 2018-05-23 23:17:04
    #include&lt;stdio.h&gt;#define MAX 10struct task_struct{ char name[10]; /*进程名称*/ float arrivetime; /*到达时间*/ float starttime; /*开始运行时间*/ float runtime; /*运行时间...
  • 时间片轮转进程调度算法(实习报告)

    千次阅读 2019-12-30 17:42:08
    时间片轮转进程调度算法实验目的和要求实验内容实验过程数据结构:部分代码:实验结果:分析和讨论完整代码 实验目的和要求 (1) 掌握时间片轮转进程调度的概念和算法 (2) 加深对处理机分配的理解 实验内容 在集成...
  • 在模拟优先权调度算法实验中,实现了 非抢占式静态优先权进程调度算法 和 非抢占式动态优先权进程调度算法。如下: (1)非抢占式静态优先权进程调度算法 #include <iostream> #include <list> #include...
  • 操作系统实验二——时间片轮转调度算法(新进程放队首和队尾两种实现方式) 情况介绍 ...如果在一个时间片用完时进程尚未运行完毕,则剥夺CPU,调度程序把它送往队列的末尾。 参数公式 周转时间=
  • Linux0.11进程分配时间片的策略

    千次阅读 2013-07-15 14:46:39
    想知道内核什么时候给进程重新分配时间片,最好的办法就是阅读源代码(其中已经打了注释)/****************************************************************************/ /* 功能:进程调度。 */ ...
  • 进程时间片的分配(优先级设定)

    千次阅读 2016-03-06 17:13:02
    系统对不同进程所分配的CPU时间的多少主要由进程的优先级决定。每一个进程都有自己的...但是对进程执行一定的操作就可以改变其动态优先级。 其操作如下: #inclde int nice(int inc); #include #include int set
  • 操作系统中进程调度是处理及管理的核心内容。 阅读本文,需要有一定的C/C++、数据结构基础。 内容介绍 采用C++编写程序,选用优先数调度算法或简单轮转法对五个进程进行调度,每个进程处于运行(Run)、就绪...
  • 模拟的情况下,进程数为8,进程所需执行时间为随机产生的整数,单位为1S,默认进程同时到达。 以下是实验的代码: Process.java是测试类,用于生成进程列表和测试三种不同的调度策略。 SJF.java是模拟实现最短作业...
  • (C语言实现)进程调度—时间片轮转调度算法

    万次阅读 多人点赞 2018-07-08 12:02:43
    一、设计目的: 本设计模拟在单处理器情况下的时间片轮转进程调度,目的是加深对进程调度工作的理解,掌握不同调度算法的优缺点。二、设计内容 设计程序模拟单处理机系统中时间片轮转进程调度算法,每个进程由一个...
  • 本次试验是使用程序来模拟操作系统中进程调度的两种不同的调度策略,分别为时间片轮转、最高优先级。模拟的情况下,进程数为8,进程所需执行时间为随机产生的整数,单位为1s,默认进程同时到达。
  • 在Linux系统中,对于用户创建的进程(线程)来说,CPU分配时间片的单位是线程还是进程? 是线程。线程是实际工作的单元[1],进程只是一个容器,用来管理一个或多个线程。 1.这是不是就意味着尽量使用多线程并发,这样...
  • 入门学习Linux常用必会60个命令实例详解doc/txt

    千次下载 热门讨论 2011-06-09 00:08:45
    halt执行时,杀死应用进程执行sync(将存于buffer中的资料强制写入硬盘中)系统调用,文件系统写操作完成后就会停止内核。若系统的运行级别为0或6,则关闭系统;否则以shutdown指令(加上-h参数)来取代。  ...
  • RR、时间片轮转算法

    千次阅读 2018-12-06 20:56:40
    #include&lt;iostream&gt; #include&lt;string&gt; #include&lt;math.h&gt; using namespace std; struct RR{  string name; //进程名 ... //进程状态,判断是否完成 ... //到达时间。...
  • 本文主要用来分享基于时间片轮转的进程调度算法,但是在分享之前,我还是先来整理一下关于进程调度的基本理论。  调度是决定或者安排事物发展次序的策略。进程的调度就是决定哪个进程来使用处理机。 操作系统的3...
  • 要求: ...采用时间片轮转法。代码:#include #include using namespace std;//设置进程的数目 static int const MAXNUM=5;//设计进程类 class process{ public: char processName;//进程的名称 int t

空空如也

空空如也

1 2 3 4 5 ... 20
收藏数 135,174
精华内容 54,069
关键字:

当进程执行的时间片用完时