操作系统课程设计报告书--进程管理子系统

摘  要

进程是程序的执行,该程序执行该程序中指定的动作。可以将其定义为程序在其中运行的执行单元。该操作系统可帮助您创建,安排和终止CPU使用的进程。由主流程创建的流程称为子流程。借助PCB(过程控制块)可以轻松控制过程操作。您可以将其视为进程的大脑,其中包含与处理相关的所有关键信息,例如进程ID,优先级,状态,CPU寄存器等

OS利用“进程实体”控制程序执行就产生了“进程”。进程是实体的运行过程,是系统进行资源分配和调度的一个独立单位;具有动态性、并发性、独立性、异步性特性。

进程的基本状态:(进程执行的间断性决定了其具有多种状态。把握各进程所属的状态对进程控制至关重要。与进程执行相关的各种共享资源有:CPU、存储器、I/O设备、时间片) 所以进程的三种基本状态有:就绪状态、运行状态、阻塞状态。

使用算法在队列上实现先进先出,实现了基本的算法调度,效果是按照顺序执行。FIFO算法维护一个先进先出队列,是一种最简单的调度算法。

关键词进程管理;FIFO;调度算法

Abstract

A process is the execution of a program that performs the actions specified in the program. It can be defined as the unit of execution in which the program runs. This operating system helps you create, schedule, and terminate processes used by your CPU. Processes created by a master process are called subprocesses. Process operations can be easily controlled with the help of PCBs (Process Control Blocks). You can think of it as the brain of a process, which contains all the key information related to processing, such as process ID, priority, status, CPU registers, etc

The OS uses the "process entity" to control program execution, resulting in a "process". A process is the running process of an entity and an independent unit of the system for resource allocation and scheduling; It has the characteristics of dynamic, concurrent, independent, and asynchronous.

Basic state of the process: (The intermittent nature of process execution determines that it has multiple states.) Knowing the state to which each process belongs is critical to process control. Various shared resources related to process execution are: CPU, memory, I/O devices, time slices) So the three basic states of a process are: ready, running, and blocking.

The algorithm is used to implement first-in-first-out on the queue, and basic algorithm scheduling is realized, and the effect is executed sequentially. The FIFO algorithm maintains a first-in-first-out queue and is the simplest scheduling algorithm.

Keywords: Process Management;FIFO;Scheduling algorithm

第1章 需求分析和任务定义

1.1需求分析

在进程管理中,算法的应用场景在需要进程按照调用顺序调度的情况下使用。算法的作用是维护一个先进先出的队列;效果是保证进程按照调用顺序执行。

1.2任务定义

算法的实现可以分成的步骤有哪些?或者接下来的课程设计工作分哪些步骤去完成。

  1. 循环读取输入的命令
  2. 通过execvp装载程序到子进程
  3. 通过PCB以及fifo队列维护控制进程调度

第2章 概要设计

2.1相关理论知识及工作原理

2.1.1 Linux的进程调度

Linux支持多进程,进程控制块PCB(Process  Control  Block)是系统中最为重要的数据结构之一,用来存放进程所必需的各种信息,PCB用结构task-struct来表示,包括进程的类型、进程状态、优先级、时钟信息等,Linux系统中,进程调度操作由schedule()函数执行,这是一个只在内核态运行的函数,函数代码为所有进程共享。

2.1.2 Linux进程调度时机

Linux的进程调度时机与现代操作系统中的调度时机基本一致,为了判断是否可以执行内核的进程调度程序来调度进程.Linux中设置了进程调度标志need-resched,当标志为1时,可执行调度程序通常,Linux调度时机分以下两种情况:

(1)主动调度:指显式调用schedule()函数明确释放CPU,引起新一轮调度.一般发生在当前进程状态改变,如:进程终止、进程睡眠、进程对某些信号处理过程中等。

(2)被动调度:指不显示调用schedule()函数,只是PCB中的need-resched进程调度标志,该域置位为1将引起新的进程调度,而每当中断处理和系统调用返回时,核心调度程序都会主动查询need-resched的状态(若置位,则主动调用schedule()函数).一般发生在新的进程产生时、某个进程优先级改变时、某个进程等待的资源可用被唤醒时、当前进程时间片用完等。

2.1.3 Linux进程调度策略

一般来说,不同用途的操作系统的调度策略是不同的,Linux进程调度是将优先级调度、时间片轮转法调度、先进先出调度综合起来应用,Linux系统中,不同类型的进程调度策略也不一样。

(1)与进程调度相关的数据结构

每个进程都是一个动态的个体,其生命周期依次定义的数据结构为:TASK-RUNNING,  TASK-INTERRUPTIBLE, TASK-UNINTERRUPTIBLE,  TASK-ZOMBIE和TASK-STOPPED.一个进程在其生存期间,状态会发生多次变化,与其数据结构相对应的即是Linux进程的状态,分别是:运行态、等待态、暂停态和僵死态。

(2)进程状态及其转换过程的描述

进程创建时的状态为不可打断睡眠,在do-fork()结束前被父进程唤醒后,变为执行状态,处于执行状态的进程被移到run-queue就绪任务队列中等待调度,适当时候由schedule()按调度算法选中,获得CPU,若采用轮转法,即时,由时钟中断触发timer-interrupt(),其内部调用schedule(),引起新一轮调度,当前进程的状态仍处于执行状态,因而把当前进程挂到ruil-queue队尾。

获得CPU且正在运行的进程若申请不到某资源,则调用sleep-on()或interruptible-sleep-on()睡眠,其task-struct进程控制块挂到相应资源的wait-queue等待队列,如果调用sleep-on(),则其状态变为不可打断睡眠,如果调用interruptible-sleep-on().则其状态变为可打断睡眠,Sleep-on()或interruptible-sleep-on()将调用schedule()函数把睡眠进程释放.

(3)进程分类和相应的进程调度策略

Linux系统中,为了高效地调度进程,将进程分成两类:实时进程和普通进程(又称非实时进程或一般进程),实时进程的优先级要高于其他进程,如果一个实时进程处于可执行状态,它将先得到执行,实时进程又有两种策略:时间片轮转和先进先出.在时间片轮转策略中,每个可执行实时进程轮流执行一个时间片,而先进先出策略每个进程按各自在运行队列中的顺序执行且顺序不能变化。

2.2 FIFO算法介绍

2.2.1 FIFO定义

FIFO是英文First In First Out的缩写,是一种先进先出的数据缓存器,他与普通存储器的区别是没有外部读写地址线,这样使用起来非常简单,但缺点就是只能顺序写入数据,顺序的读出数据,其数据地址由内部读写指针自动加1完成,不能像普通存储器那样可以由地址线决定读取或写入某个指定的地址。

2.2.2 FIFO功能

FIFO存储器是系统的缓冲环节,如果没有FIFO存储器,整个系统就不可能正常工作,它主要有几方面的功能:

(1)对连续的数据流]进行缓存,防止在进机和存储操作时丢失数据;

(2)数据集中起来进行进栈和存储,可避免频繁的总线操作,减轻CPU的负担;

(3)允许系统进行DMA操作,提高数据的传输速度。这是至关重要的一点,如果不采用DMA操作,数据传输将达不到传输要求,而且大大增加CPU的负担,无法同时完成数据的存储工作。

2.2.3 FIFO分类

FIFO的分类根据FIFO工作的时钟域,可以将FIFO分为同步FIFO和异步FIFO。同步FIFO是指读时钟和写时钟为同一个时钟。在时钟沿来临时同时发生读写操作。异步FIFO是指读写时钟不一致,读写时钟是互相独立的。同步FIFO和异步FIFO如图所示,从图中可以看到,同步FIFO 具有一个独立的时钟端口 clock,因此所有的输入输出信号都同步于 clock 信号。而在异步FIFO 结构中,写端口和读端口分别有独立的时钟,所有与写相关的信号都是同步于写时钟 wrclk,所有与读相关的信号都是同步于读时钟

    1.  问题描述和算法思想

1、在本篇文章中,算法要的解决的具体问题进行详细说明;

2、编写并调试一个模拟的进程调度程序,以加深对进程的概念及进程调度算法的理解;

3、调试运行“FIFO”调度算法,给出运行结果;

4、采用“FIFO”调度算法对五个进程进行调度。每个进程有一个进程控制块( PCB)表示。进程控制块可以包含如下信息:进程名、到达时间、需要运行时间、已用CPU时间、进程状态等等;

5、每个进程的状态可以是就绪 W(Wait)、运行R(Run)、或完成F(Finish)三种状态之一。 每进行一次调度程序都打印一次运行进程、就绪队列、以及各个进程的 PCB,以便进行检查。重复以上过程,直到所要进程都完成为止。

2.4 程序流程图

如下是FIFO调度队列的流程图,也是程序设计的流程图。如图2-1所示。

第3章 详细设计

3.1 运行环境和编程工具

程序使用vscode工具安装c插件,使用c 语言实现。开发环节和编译工具如图3-1所示。

图3-1 开发工具

3.2 模块划分及关系

算法包含的重要的类或者方法有哪些,这些类或者方法之间调用关系如何?

一个队列 que1.h  

一个主程序sh2.c

3.3 程序源代码

QUEUE* CreateQueue(void){

        QUEUE* pNewQueue=(QUEUE*)malloc(sizeof(QUEUE));

        if(pNewQueue==NULL)

                return NULL;

        pNewQueue->count=0;

        pNewQueue->front=pNewQueue->rear=NULL;

        return pNewQueue;

};

void Enqueue(QUEUE* pQueue, int item){

        QUEUE_NODE* Newptr=(QUEUE_NODE*)malloc(sizeof(QUEUE_NODE));

        if (Newptr==NULL)

                return ;

        Newptr->data = item;

        Newptr->next = NULL;

        if(pQueue->count == 0){

                pQueue->front=pQueue->rear=Newptr;

        }

        else{

                pQueue->rear->next=Newptr;

                pQueue->rear=Newptr;

        }

        pQueue->count++;

};

int Dequeue(QUEUE* pQueue){

        QUEUE_NODE* delLoc=NULL;

        int item;

        if(pQueue->count==0)

                return 0;

        delLoc=pQueue->front;

        item=delLoc->data;

        if(pQueue->count==1){

                pQueue->front=pQueue->rear=NULL;

        }

        else{

              pQueue->front=delLoc->next;

        }

        free(delLoc);

        pQueue->count--;

        return item;

};

int emptyQueue(QUEUE *queue)

{

       return(queue->count == 0);

}

QUEUE *DestroyQueue(QUEUE *queue)

{

       QUEUE_NODE *deletePtr;

       if(queue)

       {

              while(queue->front != NULL)

              {

              queue->front->data = 0;

              deletePtr = queue->front;

              queue->front = queue->front->next;

              free(deletePtr);

              }

       free(queue);

       }

return NULL;

}

  sh    git:(master)

int main()

{

       struct sigaction old_sa;

       struct sigaction new_sa;

       memset(&new_sa, 0, sizeof(new_sa));

       qrun = CreateQueue();

       qwait = CreateQueue();

       qready = CreateQueue();

       srand((unsigned)time(NULL));

       char *arglist[MAXARGS+1];        

       int   numargs;                    

       char argbuf[ARGLEN];                  

       char *makestring();                  

       //order();

       pid_t pid;

       for(int k=0; k<10; k++)

       {

              numargs = 0;

              printf("%s", "请输入命令");

             

              if ( gets(argbuf) && *argbuf ) {

                     arglist[numargs++] = *argbuf;

              }

              pid=fork();

             

              if(pid<0){

                     perror("fork fail");

              }

              else if(pid == 0){//child

                     printf("child\n");

                     execvp(arglist[0], arglist);

                     new_sa.sa_handler = &signal_handler2;

                     sigaction(SIGUSR1, &new_sa, &old_sa);

                     while(1);

                     exit(0);

              }

              else{//parent

                     printf("parent\n");

                     PCB[k].pid = pid;

                     PCB[k].remaining_tq = DEFAULT_TQ;

                     //SJF[k] = rand() % 15;

                     //PCB[k].exec_time = SJF[k];

                     PCB[k].exec_time = 10;

              }

       }

for(int k=0; k<10; k++)

       {

              printf("PID : %d\n", PCB[k].pid);

              printf("TQ : %d\n", PCB[k].remaining_tq);

              printf("Exe : %d\n", PCB[k].exec_time);

              Enqueue(qready, k);

       }

       new_sa.sa_handler = &signal_handler;

       sigaction(SIGALRM, &new_sa, &old_sa);

       fire(1);

       while (1);

}

void order()

{

       int temp;

       int i,j,k;

       for(i=0; i<MAXPROC; i++)

       {

              SJF[i] = rand() % 15;

       }

       for(j=0; j<MAXPROC; j++)

       {

              for(k=0; k<MAXPROC-1; k++)

              {

                     if(SJF[k] > SJF[k+1])

                     {

                            temp = SJF[k];

                            SJF[k] = SJF[k+1];

                            SJF[k+1] = temp;

                     }

              }

       }

}

void fire(int interval_sec)

{

       struct itimerval new_itimer, old_itimer;

       new_itimer.it_interval.tv_sec = 1;

       new_itimer.it_interval.tv_usec = 0;

       new_itimer.it_value.tv_sec = interval_sec;

       new_itimer.it_value.tv_usec = 0;

       setitimer(ITIMER_REAL, &new_itimer, &old_itimer);

}

void FIFO()

{

       ptr = qready->front->data;

       if(PCB[ptr].exec_time > 0)

       {

              PCB[ptr].exec_time--;

              printf("EXE : %d\n", PCB[ptr].exec_time);

              if(PCB[ptr].exec_time == 0)

              {

                     Dequeue(qready);

                     kill(PCB[ptr].pid, SIGUSR1);

              }

       }

       else

       {

              Dequeue(qready);

              kill(PCB[ptr].pid, SIGUSR1);

       }

}

void RR()

{

       ptr = qready->front->data;

       if(PCB[ptr].remaining_tq > 0)

       {

              printf("TQ : %d PCB[0].TQ : %d\n", PCB[ptr].remaining_tq, PCB[0].remaining_tq);

              PCB[ptr].remaining_tq--;

              PCB[ptr].exec_time--;

              printf("TQ : %d PCB[0].TQ : %d\n", PCB[ptr].remaining_tq, PCB[0].remaining_tq);

              printf("EXE : %d\n", PCB[ptr].exec_time);

              if(PCB[ptr].exec_time == 0)

              {

                     Dequeue(qready);

                     kill(PCB[ptr].pid, SIGUSR1);

              }

       }

       else if(PCB[ptr].remaining_tq == 0)

       {

              PCB[ptr].remaining_tq = DEFAULT_TQ;

              Enqueue(qready, Dequeue(qready));

       }

}

void signal_handler(int signo)

{

       if(emptyQueue(qready))

       {

              DestroyQueue(qrun);

              DestroyQueue(qready);

              DestroyQueue(qwait);

              exit(0);

       }

       FIFO();

}

void signal_handler2(int signo)

{

       ptr = qready->front->data;

        if(PCB[ptr].remaining_tq > 0)

        {

                printf("TQ : %d PCB[0].TQ : %d\n", PCB[ptr].remaining_tq, PCB[0].remaining_tq);

                PCB[ptr].remaining_tq--;

                PCB[ptr].exec_time--;

                printf("TQ : %d PCB[0].TQ : %d\n", PCB[ptr].remaining_tq, PCB[0].remaining_tq);

                printf("EXE : %d\n", PCB[ptr].exec_time);

                if(PCB[ptr].exec_time == 0)

                {

                        Enqueue(qwait, Dequeue(qready));

                }

        }

        else if(PCB[ptr].remaining_tq == 0)

        {

                PCB[ptr].remaining_tq = DEFAULT_TQ;

                Enqueue(qready, Dequeue(qready));

              if(PCB[ptr].exec_time == 0)

              {

                     Enqueue(qwait, Dequeue(qready));

              }

        }

}

4章 程序实现及测试

4.1程序实现与测试

1 启动

2 第一次输入

3 第二次输入

4 捕获信号退出

4.2 结果分析

从程序功能运行测试的结果中。完成了算法,进度调度正常,能够输入指令执行进程,捕获信号;程序功能正常。

总结

PCB中设置rt-priority数据项,其值是实时进程专用的调度优先级,实时进程的可用时间片的初始值即为该值,该优先级也可以用系统调用来修改,PCB中设置counter数据项,用于进程可用时间片时值的计数,初始值为rt-priority或P  riority,进程启动后该值随时钟周期递减。通过对Linux进程调度策略的简单分析,可以看出多进程的管理是一种非常复杂的并发程序设计,每个进程的状态不仅由其自身决定,而且还要受诸多外在因素的影响,而在此基础上的进程调度,为了保证操作系统的稳定性、提高效率和增加灵活性,还必须采用很多方法,这些都是值得我们去研究和探讨。

编写并调试一个模拟的进程调度程序,以加深对进程的概念及进程调度算法的理解。FIFO只是一个简单的而调度算法,实际的操作系统调度会比这个复杂很多。

参考文献

[1] Steve Rackley.无线网络技术原理与应用[M].北京:电子工业出版社,2020

[2]雷震甲主编.网络工程师教程.第4版[M].北京:清华大学出版社,2018

[3]赵冬梅,裴佳欢.混合式教学在“大学计算机”课程中的应用探究[J]. 中小学电教. 2019(06)

[4]曾明星,周清平,蔡国民,王晓波.基于MOOC的翻转课堂教学模式研究[J].中国电化教育. 2019(04)

[5]冯宇彤. 基于FIFO和优先级序列CAN总线系统研究[D].南京信息工程大学,2021.

[6]陈婷婷,陆锋,万书芹,邵杰.一种延迟可控的异步FIFO电路设计[J].微电子学,2022,52(01):42-46.

[7]江波.操作系统中页面置换算法的对比研究[J].广西民族师范学院学报,2010,27(03):56-59.

完整资源文件见链接:https://download.csdn.net/download/Abelon/88306355

  • 0
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

Abelon

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值