coursera 《现代操作系统》

什么是独占设备技术?为什么说 “SPOOLing不是独占设备的”?

百度百科没有解释,从教材中找到了:

 第二章

取数指令

  • load To load a value from memory, you copy the data from memory into a register.
  • store To store a value to memory, you copy the data from a register to memory.

控制转移

不知道英文是不是 go to 

 A programming statement that forwards a user to a different section of the program. 

PSW

The Program status word[1][2] (PSW) is an IBM System/360 architecture and successors control register which performs the function of a Status register and Program counter in other architectures, and more.

PSW即程序状态字(有些教材也叫程序状态寄存器),Program Status Word。
可用于OS在管态(系统态)和目态(用户态)之间的转换
程序状态寄存器PSW是计算机系统的核心部件——运算器的一部分,PSW用来存放两类信息:一类是体现当前指令执行结果的各种状态信息,称为状态标志,如有无借位进位(CY位)、有无溢出(OF位)、结果正负(SF位)、结果是否为零(ZF位)、奇偶标志位(PF位)等;另一类是存放控制信息,称为控制状态,如允许中断(IF位),跟踪标志(TF位),方向标志(DF)等。有些机器中将PSW称为标志寄存器FR(Flag Register)。
 

Two important hidden registers are the PC, which is short for the program counter and IR, which is short for the instruction register.

PC, the Program Counter

PC is a 32-bit hidden register.

The PC is a poor description for what a PC does. It does not count programs, and is not really a counter at all. The PC holds the address of the current instruction being executed. At times, the PC may hold the address plus 4, attempting to anticipate the "next" instruction to be executed.

Recall that, in MIPS, instructions are 4 bytes long and thus use up 4 consecutive memory locations. Since instructions are words, they must be stored at word-aligned addresses, i.e., at addresses divisible by 4.

If you inspect the low two bits of the PC (i.e., PC1..0), you'd notice that they always end in 00.

Unless a branch or jump occurs, PC is updated to PC + 4, the address of the next instruction in memory. Notice that the next instruction in memory is not the same as the next instruction to be executed. It's possible for the next instruction to be executed to be some other instruction besides PC + 4.

IR, the Instruction Register

IR is a 32-bit hidden register.

At least, IR has a reasonable name. This register actually stores an instruction. In particular, it stores the instruction given by PC.

By storing an instruction in a register, we can use the output of the register to control other parts of the CPU, so the instruction can be executed.

堆栈与压栈

计算机中的堆栈(Stack)是一组能存储和取出数据的暂时存储单元,所有信息的存入和取出均按照后进先出(LIFO)或先进后出(FILO)的原则进行。

堆栈存取方式决定了其“一端存取”的特点,数据按顺序存入堆栈称为进栈或压栈(Push),堆栈中一个单元的数据称为栈项,栈项按与进栈相反的顺序从堆栈中取出称为出栈或弹出(Pop),最后进栈的数据或最先出栈的数据称为栈顶元素。

1.寄存器堆栈

寄存器堆栈又称串联堆栈、硬堆栈。某些计算机在CPU中设置了一组专门用于堆栈的寄存器,每个寄存器可保存一个字的数据。因为这些寄存器直接设置于CPU中,所以它们是极好的暂存单元。CPU通过进栈指令(PUSH)把数据存入堆栈,通过出栈指令(POP)把数据从堆栈中取出。

寄存器堆栈如图4-14所示:⑴空栈表示栈顶无数据,即位于栈顶的寄存器中无可用的数据;⑵存入数据a,即把数据a存入栈顶,数据a可以来自主存、程序计数器PC等部件;⑶再存入数据b,数据b位于栈顶,先进入的数据a则移至下一个寄存器;⑷执行出栈操作,位于栈顶的数据b被取出,与此同时数据a移至栈顶。

418.gif

从寄存器堆栈的数据进栈操作结果可见,最后进栈的数据位于栈顶,位于栈顶的数据出栈时最先被取出。在寄存器堆栈中,还必须有“栈空”和“栈满”的指示,以防在栈空时企图执行出栈、在栈满时企图执行进栈的误操作。这可以通过另外设置一个计数器来实现:每次进栈,计数器加1,计数值等于堆栈中寄存器个数时表示栈满;每次出栈,计数器减1,该计数值等于0时表示栈空。

寄存器堆栈的特点是仅有一个出入口,后进先出,且堆栈的容量固定,不需要占用主存。

堆栈的作用: 

堆栈中对数据的操作具有后进先出的特点,因此,凡是以后进先出方式进行的信息传送都可以用堆栈很方便地实现。例如,在子程序的调用中,用堆栈存放主程序的返回地址,实现子程序的嵌套和递归调用;在程序中断处理中,用堆栈存放多级中断的相关信息,实现多级中断的嵌套。

特权指令

特权指令指具有特殊权限的指令。这类指令只用于操作系统或其他系统软件,一般不直接提供给用户使用。

那么操作系统是不是只能执行特权指令呢?按照权限来说,应该也能执行用户指令


问:从用户态转换到内核态是通过设置程序状态字(PSW)寄存器的某一位(某几位)完成的。

在程序状态字寄存器中专门设置一位,根据运行程序对资源和指令的使用权限而设置不同的CPU状态。疑问:我感觉是对的啊,coursera 显示是错的

第三章 进程与线程

三状态模型

 问:

为什么没有从 `就绪`-->`等待`态?

因为发生等待态的条件,需要进程在运行时才能满足,比如调用OS服务,进行IO读写;所以只能从 `运行 `到`就绪`态

为什么没有从 `等待`-->`运行`态?

程序进入运行态需要被调度程序选中,而调度程序只会选择就绪态。为什么呢?因为等待态还在等待一个事件完成,事件没完成不能运行或者没有必要去运行。

进程控制的主要功能是对系统中的所有进程实施有效的管理,它具有创建新进程、撤销已有进程、实现进程状态转换等功能。在操作系统中,一般把进程控制用的程序段称为原语,原语的特点是执行期间不允许中断,它是一个不可分割的基本单位。

进程控制:进程的创建、终止、阻塞、唤醒和切换

进程的创建

允许一个进程创建另一个进程。此时创建者称为父进程,被创建的进程称为子进程。子进程可以继承父进程所拥有的资源。当子进程被撤销时,应将其从父进程那里获得的资源归还给父进程。此外,在撤销父进程时,也必须同时撤销其所有的子进程。

在操作系统中,终端用户登录系统、作业调度、系统提供服务、用户程序的应用请求等都会引起进程的创建。操作系统创建一个新进程的过程如下(创建原语):

  1. 为新进程分配一个唯一的进程标识号,并申请一个空白的PCB(PCB是有限的)。若PCB申请失败则创建失败。
  2. 为进程分配资源,为新进程的程序和数据、以及用户栈分配必要的内存空间(在PCB 中体现)。注意:这里如果资源不足(比如内存空间),并不是创建失败,而是处于”等待状态“,或称为“阻塞状态”,等待的是内存这个资源。
  3. 初始化PCB,主要包括初始化标志信息、初始化处理机状态信息和初始化处理机控制信息,以及设置进程的优先级等。
  4. 如果进程就绪队列能够接纳新进程,就将新进程插入到就绪队列,等待被调度运行。

进程的终止

引起进程终止的事件主要有:正常结束,表示进程的任务已经完成和准备退出运行。异常结束是指进程在运行时,发生了某种异常事件,使程序无法继续运行,如存储区越界、保护错、非法指令、特权指令错、I/O故障等。外界干预是指进程应外界的请求而终止运行,如操作员或操作系统干预、父进程请求和父进程终止。

操作系统终止进程的过程如下(撤销原语):

  1. 根据被终止进程的标识符,检索PCB,从中读出该进程的状态。
  2. 若被终止进程处于执行状态,立即终止该进程的执行,将处理机资源分配给其他进程。
  3. 若该进程还有子进程,则应将其所有子进程终止。
  4. 将该进程所拥有的全部资源,或归还给其父进程或归还给操作系统。
  5. 将该PCB从所在队列(链表)中删除。

进程的阻塞和唤醒

正在执行的进程,由于期待的某些事件未发生,如请求系统资源失败、等待某种操作的完成、新数据尚未到达或无新工作做等,则由系统自动执行阻塞原语(Block),使自己由运行状态变为阻塞状态。可见,进程的阻塞是进程自身的一种主动行为,也因此只有处于运行态的进程(获得CPU),才可能将其转为阻塞状态。

阻塞原语的执行过程是:

  1. 找到将要被阻塞进程的标识号对应的PCB。
  2. 若该进程为运行状态,则保护其现场,将其状态转为阻塞状态,停止运行。
  3. 把该PCB插入到相应事件的等待队列中去。


当被阻塞进程所期待的事件出现时,如它所启动的I/O操作已完成或其所期待的数据已到达,则由有关进程(比如,提供数据的进程)调用唤醒原语(Wakeup),将等待该事件的进程唤醒。

唤醒原语的执行过程是:

  1. 在该事件的等待队列中找到相应进程的PCB。
  2. 将其从等待队列中移出,并置其状态为就绪状态。
  3. 把该PCB插入就绪队列中,等待调度程序调度。


需要注意的是,Block原语和Wakeup原语是一对作用刚好相反的原语,必须成对使用。 Block原语是由被阻塞进程自我调用实现的,而Wakeup原语则是由一个与被唤醒进程相合作或被其他相关的进程调用实现的。

进程切换

对于通常的进程,其创建、撤销以及要求由系统设备完成的I/O操作都是利用系统调用而进入内核,再由内核中相应处理程序予以完成的。进程切换同样是在内核的支持下实现的,因此可以说,任何进程都是在操作系统内核的支持下运行的,是与内核紧密相关的。

进程切换是指处理机从一个进程的运行转到另一个进程上运行,这个过程中,进程的运行环境产生了实质性的变化。

进程切换的过程如下:

  1. 保存处理机上下文,包括程序计数器和其他寄存器。
  2. 更新PCB信息。
  3. 把进程的PCB移入相应的队列,如就绪、在某事件阻塞等队列。
  4. 选择另一个进程执行,并更新其PCB。
  5. 更新内存管理的数据结构。
  6. 恢复处理机上下文。


注意,进程切换与处理机模式切换是不同的,模式切换时,处理机逻辑上可能还在同一进程中运行。如果进程因中断或异常进入到核心态运行,执行完后又回到用户态刚被中断的程序运行,则操作系统只需恢复进程进入内核时所保存的CPU现场,无需改变当前进程的环境信息。但若要切换进程,当前运行进程改变了,则当前进程的环境信息也需要改变。

写时复制

之前 UNIX 的fork是以一次一页的方式复制父进程的地址空间,太慢了,也浪费,因为子进程并不需要那么多的信息。Linux改进为写时复制,父进程将地址空间的设置为只读权限(对子进程来说),然后将地址空间的指针传递给子进程,当子进程对父进程的地址空间进行写操作的时候,就会将对应的那页复制出去,单独为子进程开辟一个空间。

疑问:保存在栈中和寄存器中有什么不一样?

用户栈与内核栈的不同?

1.进程的堆栈

     内核在创建进程的时候,在创建task_struct的同事,会为进程创建相应的堆栈。每个进程会有两个栈,一个用户栈,存在于用户空间,一个内核栈,存在于内核空间。当进程在用户空间运行时,cpu堆栈指针寄存器里面的内容是用户堆栈地址,使用用户栈;当进程在内核空间时,cpu堆栈指针寄存器里面的内容是内核栈空间地址,使用内核栈。

2.进程用户栈和内核栈的切换

    当进程因为中断或者系统调用而陷入内核态之行时,进程所使用的堆栈也要从用户栈转到内核栈。

    进程陷入内核态后,先把用户态堆栈的地址保存在内核栈之中,然后设置堆栈指针寄存器的内容为内核栈的地址,这样就完成了用户栈向内核栈的转换;当进程从内核态恢复到用户态之行时,在内核态之行的最后将保存在内核栈里面的用户栈的地址恢复到堆栈指针寄存器即可。这样就实现了内核栈和用户栈的互转。

    那么,我们知道从内核转到用户态时用户栈的地址是在陷入内核的时候保存在内核栈里面的,但是在陷入内核的时候,我们是如何知道内核栈的地址的呢?

    关键在进程从用户态转到内核态的时候,进程的内核栈总是空的。这是因为,当进程在用户态运行时,使用的是用户栈,当进程陷入到内核态时,内核栈保存进程在内核态运行的相关信心,但是一旦进程返回到用户态后,内核栈中保存的信息无效,会全部恢复,因此每次进程从用户态陷入内核的时候得到的内核栈都是空的。所以在进程陷入内核的时候,直接把内核栈的栈顶地址给堆栈指针寄存器就可以了。

见第二周课程: 系统调用机制

问:
进程运行时,其硬件状态保存在相应寄存器中;当它被切换下CPU时,其硬件状态保存在内核栈中。

线程在进程中的共享 

链接:https://www.nowcoder.com/questionTerminal/74bb7a1b3d5640e9aedea219dcabfeaa
来源:牛客网

线程共享的环境包括:进程代码段、进程的公有数据(利用这些共享的数据,线程很容易的实现相互之间的通讯)、进程打开的文件描述符、信号的处理器、进程的当前目录和进程用户ID与进程组ID。

 
    进程拥有这许多共性的同时,还拥有自己的个性。有了这些个性,线程才能实现并发性。这些个性包括:

    1.线程ID
      每个线程都有自己的线程ID,这个ID在本进程中是唯一的。进程用此来标
   识线程。
 
    2.寄存器组的值
       由于线程间是并发运行的,每个线程有自己不同的运行线索,当从一个线
   程切换到另一个线程上 时,必须将原有的线程的寄存器集合的状态保存,以便
   将来该线程在被重新切换到时能得以恢复。
 
    3.线程的堆栈
       堆栈是保证线程独立运行所必须的。
       线程函数可以调用函数,而被调用函数中又是可以层层嵌套的,所以线程
   必须拥有自己的函数堆栈, 使得函数调用可以正常执行,不受其他线程的影
   响。

    4.错误返回码
       由于同一个进程中有很多个线程在同时运行,可能某个线程进行系统调用
   后设置了errno值,而在该 线程还没有处理这个错误,另外一个线程就在此时
   被调度器投入运行,这样错误值就有可能被修改。
       所以,不同的线程应该拥有自己的错误返回码变量。

    5.线程的信号屏蔽码
       由于每个线程所感兴趣的信号不同,所以线程的信号屏蔽码应该由线程自己管理。但所有的线程都共享同样的信号处理器。

    6.线程的优先级
       由于线程需要像进程那样能够被调度,那么就必须要有可供调度使用的参数,这个参数就是线程的优先级。

 错题:

11。

下列各种事件中,一定产生进程状态改变的事件是

运行的进程时间片用完

运行的进程正常退出

阻塞的进程被唤醒

新进程创建成功

运行的进程因种种原因而阻塞

原文地址:https://www.cnblogs.com/jay54520/p/6528191.html