操做系統思考 第二章 進程

第二章 進程

做者:Allen B. Downeyhtml

原文:Chapter 2 Processesgit

譯者:飛龍程序員

協議:CC BY-NC-SA 4.0github

2.1 抽象和虛擬化

在咱們談論進程以前,我打算先定義幾個東西:shell

  • 抽象(Abstraction):抽象是復瑣事物的簡單表示。例如,若是你開車的話,應該知道車輪向左轉的時候車也會向左行駛,反之亦然。固然,方向盤由一系列機械和傳動系統所鏈接,用於使輪子轉向,而且輪子和路面的相互做用方式也很複雜。可是做爲一個司機,你一般不須要考慮這些細節。你能夠僅僅創建方向盤的心智模型,這種心智模型就是一個抽象。編程

    軟件工程的很大一部分就是設計相似這樣的抽象,容許用戶和其它程序員使用強大而複雜的系統,而沒必要知道其實現的細節。
  • 虛擬化(Virtualization):一類很是重要的抽象就是虛擬化,它是建立可取的幻像的過程。例如,許多公共圖書館都參與了館際合做,容許它們互相借閱圖書。當我須要一本書時,有時它在個人本地圖書館的架子上,但更多狀況下它會被運到其它的館藏中。不管是哪種,我都會收到它可借閱的提醒。我並不須要知道它來自哪裏,我也不須要知道個人圖書館擁有哪一本書。通常來講,這個系統建立了一個幻象,好像個人圖書館擁有全世界的每一本書。瀏覽器

    在物理上,個人圖書館的館藏可能很小,可是虛擬上我能得到的館藏包含了館際合做的每一本書。
    
    另一個例子,大多數電腦都只鏈接到一個網絡中,而這個網絡又連接到其它網絡,等等。咱們所談論的「互聯網」,是一系列網絡和協議的合集,它將數據包從一個網絡傳送到另外一個網絡。從用戶和程序員的角度來看,整個系統的行爲就像是互聯網的每臺計算機都互相鏈接。物理鏈接的數量十分少,可是虛擬鏈接的數量十分龐大。

「虛擬」這個詞一般用於虛擬機的語境中,它是一種軟件,能夠建立運行特定系統的專用計算機的幻象。實際上,虛擬機可能和其它虛擬機一塊兒運行在不一樣的操做系統上。安全

在虛擬化的語境中,咱們一般把真實發生的事情叫作「物理的」,而把虛擬上發生的事情叫作「邏輯的」或者「抽象的」。bash

2.2 隔離

工程最重要的原則之一就是隔離(Isolation):當你設計一個帶有多個組件的系統時,將它彼此隔離是個很好的方法,這樣某個組件中的改變就不會對其它組件形成不良影響。網絡

操做系統最重要的目標之一,就是將每一個進程和其它進程隔離,使程序員沒必要考慮每一個可能的交互狀況。提供這種隔離的軟件對象叫作進程(Process)。

進程是表示運行中程序的軟件對象。我按照面向對象編程把它稱之爲「軟件對象」。工程一個對象包含數據,而且提供用於操做數據的方法。進程正是包含如下數據的對象:

  • 程序文本,一般是機器語言的指令序列。

  • 程序相關的數據,包括靜態數據(編譯時分配)和動態數據,後者包括運行時的棧和堆。

  • 任何等待中的IO狀態。例如,若是進程正在等待從磁盤中讀取的數據,或者從網絡到達的數據包,這些操做的狀態也是進程的一部分。

  • 程序的硬件狀態,這包括儲存在寄存器中的數據,狀態信息,以及程序計數器,它表示當前執行了哪一個指令。

一般一個進程運行一個程序,可是對於進程來講,加載並運行新的程序也是可能的。

也能夠在多於一個進程中運行相同的程序,這很是常見。這種狀況下,各個進程共享程序文本,可是擁有不一樣的數據和硬件狀態。

大多數操做系統提供了隔離進程的基本功能:

  • 多任務:大多數操做系統有能力在幾乎任什麼時候候中斷一個進程,保存它的硬件狀態,而且在之後恢復它。一般,程序員不須要考慮這些中斷。程序的行爲就像在一個專用的處理器上持續運行,除了兩條指令之間的時間是不可預測的。

  • 虛擬內存:大多數操做系統會建立幻象,每一個進程看似擁有獨立內存片而且孤立於其餘進程。一樣,程序員一般也不須要考慮虛擬內存如何工做,他們能夠當作每一個程序都擁有專用的內存片來處理。

  • 設備抽象:運行於同一臺計算機的進程共享磁盤、網絡接口、顯卡和其它硬件。若是進程直接和這些硬件交互而不加協調,就必定會產生混亂。例如,一個進程預期的網絡數據可能會被另外一個進程讀取。或者多個進程可能嘗試在磁盤的相同位置儲存數據。操做系統負責經過提供合適的抽象來維持秩序。

做爲程序員,你不須要知道太多關於這些功能如何實現的事情。可是若是你很好奇,你能夠在這個屏蔽層的後面發現一大堆有趣的事情。並且,若是你知道其中所發生的事情,你會成爲更好的程序員。

2.3 Unix 進程

當我寫這本書的時候,我最關注的進程就是個人文本編輯器,Emacs。偶爾我也會切換到終端窗口,它是一個運行Unix shell並提供命令行接口的窗口。

當我移動鼠標時,窗口的管理器會被喚醒,看到鼠標在終端窗口上方,而且喚醒終端。終端又喚醒shell。若是我在shell中鍵入make,它就會建立一個新的進程來運行Make。Make會建立另外一個進程來運行LaTeX,以後另外一個進程會顯示結果。

若是我須要查詢一些東西,我會切換到另外一個桌面,這會再次喚醒窗口管理器。若是我點擊Web瀏覽器的圖標,窗口管理器會建立進行來運行Web瀏覽器。許多瀏覽器,相似Chrome,會爲每一個窗口和每一個選項卡建立新的進程。

而且這些只是我所瞭解的進程,同時還有許多其它進程「在後臺」運行。它們中許多都在執行操做系統相關的工做。

Unix命令ps能打印出運行中進程的信息。若是你在終端裏運行它,可能會看到這些:

PID TTY          TIME CMD
 2687 pts/1    00:00:00 bash
 2801 pts/1    00:01:24 emacs
24762 pts/1    00:00:00 ps

第一列是惟一的進程ID。第二列是建立進程的終端,「TTY」表明「電傳打字機」(Teletypewriter),它是原始的機械終端。

第三行是用於該進程的處理器時間總計,依次爲時、分、秒。最後一行是所運行進程的名稱。這個例子中,bash是shell的名稱,用於解釋我鍵入到終端中的命令。Emacs是個人文本編輯器,而ps是生成這份輸出的程序。

一般,ps只會列出有關當前終端的進程。若是你使用-e選項,你會獲得全部進程(也包括屬於其餘用戶的進程,我認爲這是個安全缺陷)。

在個人系統上有233個進程,下面是它們的一部分:

PID TTY          TIME CMD
    1 ?        00:00:17 init
    2 ?        00:00:00 kthreadd
    3 ?        00:00:02 ksoftirqd/0
    4 ?        00:00:00 kworker/0:0
    8 ?        00:00:00 migration/0
    9 ?        00:00:00 rcu_bh
   10 ?        00:00:16 rcu_sched
   47 ?        00:00:00 cpuset
   48 ?        00:00:00 khelper
   49 ?        00:00:00 kdevtmpfs
   50 ?        00:00:00 netns
   51 ?        00:00:00 bdi-default
   52 ?        00:00:00 kintegrityd
   53 ?        00:00:00 kblockd
   54 ?        00:00:00 ata_sff
   55 ?        00:00:00 khubd
   56 ?        00:00:00 md
   57 ?        00:00:00 devfreq_wq

init是操做系統啓動時首先建立的進程。它又會建立許多其它進程,以後會閒置,直到它建立的進程運行完畢。

kthreadd是操做系統用於建立新的「線程」的進程。以後咱們將會談論更多關於線程的東西,可是你暫時你能夠認爲線程是一種進程。

相關文章
相關標籤/搜索