(7)操作系统--第一章第二章总结

系统状态,为构造高效可靠的操作系统,硬件必须区分核心态和用户态,操作系统在核心态运行,可以执行特权指令;用户程序在目态运行,不可执行特权指令。系统运行时用户态和系统态和用户态是经常切换的,由用户态切换到系统态通过中断或访管,系统态切换到用户态通过置程序状态字。
堆是保存动态变量的,目态的栈用于保存函数调用的返回点、参数、局部变量、返回值。因为函数调用是可以嵌套的,嵌套调用的次序和返回的次序恰好相反,所以栈是唯一可选择的正确的数据结构。操作系统的栈,保存操作系统内部函数调用的返回点、参数、局部变量,返回值;除此之外,系统栈还有一个重要用途,就是保存中断现场,中断发生时,硬件中断装置将PSW和PC压到系统栈,再根据中断原因取来中断向量送到PSW和PC寄存器,从而转到中断处理程序。
系统调用形式和SVC形式,大家应该知道系统调用形式如write(fd,buf,count)经过编译后会变成SVC形式,此处涉及到了参数和返回值的传递,传递的媒介是用户栈和寄存器。
SVC 用于产生系统函数的调用请求。例如,操作系统通常不让用户程序直接访问硬件,而是通过提供
一些系统服务函数,让用户程序使用 SVC 发出对系统服务函数的呼叫请求,以这种方法调用它们来间接
访问硬件。因此,当用户程序想要控制特定的硬件时,它就要产生一个 SVC 异常,然后操作系统提供的
SVC 异常服务例程得到执行,它再调用相关的操作系统函数,后者完成用户程序请求的服务
,进程是操作系统中最重要的概念之一,定义为可参与并发执行的程序。进程有三种基本状态:运行态、就绪态、等待态。三种基本状态及其转换。进程是走走停停的,停下来的时候要保存现场,即各种寄存器的当前值,保存在什么地方呢?PCB,下次运行时由PCB恢复现场,从上次中断的位置开始继续执行。
PCB里除去现场之外还有一组其它信息,如进程的地址,状态等等,它们都是系统管理进程需要的。系统管理进程是通过对PCB的管理实现的。管理时回把PCB组织成一些链,包括就绪链、等待链等,每种等待原因都有一个等待链。
线程的概念比进程出现的晚一些,定义为进程中的一个执行流,进程是资源分配单位,如存储资源;线程是处理机的分配单位。由于线程是执行流,所以会有嵌套函数调用,因而每个线程要有个目态栈;核心栈呢?如果是用户级别线程,每个进程有一个系统栈,如果是核心级别线程,每个线程一个系统栈。
如果是用户级别的线程,一个进程中的两个线程,其中一个进入操作系统,使用该进程的系统栈,如果该线程等待或被剥夺处理机,系统栈是非空的,该进程的另外一个线程不会进入操作系统,不会使用系统栈,直到前一个线程返回用户态,才有可能执行另外一个线程,而这个线程进入系统态时,系统栈是空的,为什么呢?前一个线程已经离开系统态回到目态,此时系统栈必然是空的,所以同一进程中的两个线程使用同一个系统栈没有冲突。而系统级别线程就不同了,进程中的一个线程进入操作系统,可能等待或被剥夺处理机,此时系统可能调度该进程的另外一个线程,该线程进入操作系统,不能使用前一个线程所用的系统栈,因为它不是空的。

  1. 进程的概念:可参与并发执行的程序;

  2. 进程状态及状态转换;
    运行态:进程占用CPU,并在CPU上运行;
    就绪态:进程已经具备运行条件,但是CPU还没有分配过来;
    阻塞态:进程因等待某件事发生而暂时不能运行;
    运行—》就绪:这是有调度引起的,主要是进程占用CPU的时间过长
    就绪—》运行:运行的进程的时间片用完,调度就转到就绪队列中选择合适的进程分配CPU
    运行—》阻塞:发生了I/O请求或等待某件事的发生
    阻塞—》就绪:进程所等待的事件发生,就进入就绪队列
    以上4种情况可以相互正常转换,不是还有两种情况吗?
    阻塞–》运行:即使给阻塞进程分配CPU,也无法执行,操作系统載进行调度时不会載阻塞队列进行挑选,其调度的选择对象为就绪队列:
    就绪–》阻塞:因为就绪态根本就没有执行,何来进入阻塞态?
    可运行态:他是运行态和就绪态的合并,表示进程正在运行或准备运行,Linux 中使用TASK_RUNNING 宏表示此状态。
    浅度睡眠态:进程正在睡眠(被阻塞),等待资源到来是唤醒,也可以通过其他进程信号或时钟中断唤醒,进入运行队列。Linux 使用TASK_INTERRUPTIBLE 宏表示此状态。
    深度睡眠态:其和浅度睡眠基本类似,但有一点就是不可其他进程信号或时钟中断唤醒。Linux 使用TASK_UNINTERRUPTIBLE 宏表示此状态。
    暂停状态:进程暂停执行接受某种处理。如正在接受调试的进程处于这种状态,Linux 使用TASK_STOPPED 宏表示此状态。
    僵死状态:进程已经结束但未释放PCB,Linux 使用TASK_ZOMBIE 宏表示此状态。

  3. 进程现场,及其控制块;
    是为了管理进程设置的一个数据结构。是系统感知进程存在的唯一标志。
    通常包含如以下的信息:
    (1)进程标识符(唯一)
    (2)进程当前状态,通常同一状态的进程会被放到同一个队列;
    (3)进程的程序和数据地址
    (4)进程资源清单。列出所拥有的除CPU以外的资源记录。
    (5)进程优先级。反应进程的紧迫程度
    (6)CPU现场保护区。记录中断时的CPU状态
    (7)进程队列的PCB的链接字。
    (9)进程相关的其他信息。记账用的,如占用CPU多长时间等。

  4. 进程的组成与上下文;
    进程上下文一般在进程切换中提到,进程控制块PCB,保存着进程的诸多详细信息,当进程要切换时当前进程的寄存器内容以及内存页表的详细信息等等内容,也就是关于描述进程的信息。

  5. 进程的队列结构。
    创建共享的进程队列。maxsize是队列中允许的最大项数。如果省略此参数,则无大小限制。底层队列使用管道和锁定实现。另外,还需要运行支持线程以便队列中的数据传输到底层管道中

  6. 在UNIX系统中,如何创建进程,系统调用fork, execl, wait, exit,vfork,execve的工作原理,在课件中有完整动态展示;
    Pid = fork()子进程是父进程的复制品
    execl(prog, arg0,…,argn-1,0) 以arg0,…,argn-1为参数执行prog 覆盖原来程序,从第一条指令开始执行
    exit(status)Status为终止状态唤醒父进程等待子进程终止
    pid=wait(&status)返回终止子进程编号参数为子进程的终止状态
    vfork
    只复制控制结构(proc+user);
    不复制地址空间(code+data)
    父子进程共享地址空间
    使用
    父进程使用 vfork 创建子进程;
    子进程与父进程共享地址空间;
    子进程使用 execve 改变其虚拟地址空间.

  7. 线程的概念,线程与进程之间的关系,线程的结构,用户级别的线程与系统级别的线程,线程的实现。
    进程中一个相对独立的执行流

作业概念
用户要求计算机系统为其完成的计算任务集合。
作业步(job step)
作业处理过程中一个相对独立的步骤
一般一个作业步可由一个进程完成
某些作业步之间可以并行
作业分类
批处理作业
交互式作业

作业与进程
作业进入内存后变为进程
一个作业通常与多个进程相对应
进程与线程
一个进程一般包含多个线程,至少包含一个线程
不支持多线程的系统,可视为单线程进程

Java线程四种基本状态
New:新建的线程
Runnable:可运行状态
Blocked:封锁状态
Dead:终止状态.
在这里插入图片描述

设有8个程序,执行次序如下图所示,试用fork,execl,wait,exit系统调用描述之.
在这里插入图片描述

main
{
	int pid1,pid2,pid3,pid4,pid5,pid6,pid7,pid8;
	int  end_p1=end_p2=end_p3=end_p4=end_p5==end_p8=0;
	int pid, status;
	if((pid1=fork())= =0) execl("P1",0);
    wait(&status);
    if((pid2=fork())= =0) execl("P2",0);
    if((pid3=fork())= =0) execl("P3",0);
    if((pid4=fork())= =0) execl("P4",0);
	do
	{        //等待结束
          pid=wait(&status);
          if(pid= =pid2) end_p2=1;
          if(pid= =pid3) end_p3=1;
          if(pid= =pid4) end_p4=1;
    }while(end_p2= =0);
	if((pid5=fork())= =0) execl("P5",0);
    if((pid6=fork())= =0) execl("P6",0);
    do
	{        //等待P3和P6结束
        pid=wait(&status);
        if(pid= =pid3) end_p3=1;
        if(pid= =pid4) end_p4=1;
        if(pid= =pid5) end_p5=1;
        if(pid= =pid6) end_p6=1;
    }while(end_p3= =0||end_p6= =0);
    if((pid7=fork())= =0) execl("P7",0);
    do{        //等待P4,P5,P7结束
            pid=wait(&status);
            if(pid= =pid4) end_p4=1;
            if(pid= =pid5) end_p5=1;
            if(pid= =pid7) end_p7=1;
    }while(end_p4= =0||end_p5= =0||end_p7= =0);
     if((pid8=fork())= =0) execl("P8",0);
     wait(&status);
     exit(0);
}

在这里插入图片描述

进程转换完整分解图:
在这里插入图片描述
1:创建一个进程:
建立一个PCB,分配存储资源,加载程序(放入存储空间),初始化PCB(地址映射寄存器,PSW,PC=0,SP=栈底,通用寄存器regs=0, 浮点寄存器fregs=0),进入就绪队列中
2:就绪进程被调度选中:进入kernel运行,切换PCB,恢复地址映射寄存器,通用寄存器,SP
3:置PSW,进入目态运行
4:发生中断:进入kernel运行,现场核心栈
4.1:中断嵌套,在kernel运行中嵌套
4.2.1:嵌套结束,发生等待资源或者IO中断等待事件,进入等待队列,保存核心级别现场到PCB,PCB入等待队列
4.2.2:被剥夺运行,进入就绪队列
5:等待事件发生IO传输结束或者资源被分配了,进入就绪状态,由等待队列转移到就绪队列

参考:
https://blog.csdn.net/Beyond_2016/article/details/81357705
https://www.cnblogs.com/bugutian/

发布了133 篇原创文章 · 获赞 11 · 访问量 2924

猜你喜欢

转载自blog.csdn.net/qq_43410618/article/details/104790966