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。

下列各種事件中,一定產生進程狀態改變的事件是

運行的進程時間片用完

運行的進程正常退出

阻塞的進程被喚醒

新進程創建成功

運行的進程因種種原因而阻塞

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM