1. 程序有那幾種狀态,狀态轉換圖,及導緻轉換的事件
如上圖所示,程序包括三種狀态:就緒态、運作态和阻塞态。詳細說明如下:
注意:建立和退出不是程序的狀态。阻塞和就緒的差別:阻塞是等待除CPU以外的資源,而就緒等待的是CPU資源。
- 就緒——執行:對就緒狀态的程序,當程序排程程式按一種標明的政策從中選中一個就緒程序,為之配置設定了處理機後,該程序便由就緒狀态變為執行狀态;
- 執行——阻塞:正在執行的程序因發生某等待事件而無法執行,則程序由執行狀态變為阻塞狀态,如程序提出輸入/輸出請求而變成等待外部裝置傳輸資訊的狀态,程序申請資源(主存空間或外部裝置)得不到滿足時變成等待資源狀态,程序運作中出現了故障(程式出錯或主存儲器讀寫錯等)變成等待幹預狀态等等;
- 阻塞——就緒:處于阻塞狀态的程序,在其等待的事件已經發生,如輸入/輸出完成,資源得到滿足或錯誤處理完畢時,處于等待狀态的程序并不馬上轉入執行狀态,而是先轉入就緒狀态,然後再由系統程序排程程式在适當的時候将該程序轉為執行狀态;
- 執行——就緒:正在執行的程序,因時間片用完而被暫停執行,或在采用搶先式優先級排程算法的系統中,當有更高優先級的程序要運作而被迫讓出處理機時,該程序便由執行狀态轉變為就緒狀态。
2. 程序和線程的差別
程序可以認為是程式執行時的一個執行個體。程序是系統進行資源配置設定的獨立實體, 且每個程序擁有獨立的位址空間。一個程序無法直接通路另一個程序的變量和資料結構, 如果希望讓一個程序通路另一個程序的資源,需要使用程序間通信,比如:管道,檔案, 套接字等。
一個程序可以擁有多個線程,每個線程使用其所屬程序的棧空間。 線程與程序的一個主要差別是,同一程序内的多個線程會共享部分狀态, 多個線程可以讀寫同一塊記憶體(一個程序無法直接通路另一程序的記憶體)。同時, 每個線程還擁有自己的寄存器和棧,其它線程可以讀寫這些棧記憶體。
線程是程序的一個特定執行路徑。當一個線程修改了程序中的資源, 它的兄弟線程可以立即看到這種變化。
以下是分點小結:
- 程序是系統進行資源配置設定的基本機關,有獨立的記憶體位址空間; 線程是CPU排程的基本機關,沒有單獨位址空間,有獨立的棧,局部變量,寄存器, 程式計數器等。
- 建立程序的開銷大,包括建立虛拟位址空間等需要大量系統資源; 建立線程開銷小,基本上隻有一個核心對象和一個堆棧。
- 一個程序無法直接通路另一個程序的資源;同一程序内的多個線程共享程序的資源。
- 程序切換開銷大,線程切換開銷小;程序間通信開銷大,線程間通信開銷小。
- 線程屬于程序,不能獨立執行。每個程序至少要有一個線程,成為主線程
3. 線程獨享那些資源,共享那些資源?
線程獨享:
- 線程ID
- 上下文:包括程式計數器,棧指針,寄存器資訊
- 棧空間
- errno錯誤碼
- 信号屏蔽字
- 排程優先級
線程共享:
- uid(使用者ID),gid(組ID)
- 檔案描述符
- 堆空間
- 目前工作目錄
- 信号處理方式
4. 程序控制塊(task_struct)包含内容?
task_struct是Linux核心的⼀一種資料結構,它會被裝載到RAM裡并且包含着程序的資訊。
每個程序都把它的資訊放在 task_struct 這個資料結構裡,task_struct 包含了這些内容:
标示符 (pid): 描述本程序的唯一标示符,用來差別其他程序。
狀态 :任務狀态,退出代碼,退出信号等。
優先級 :相對于其他程序的優先級。
程式計數器:程式中即将被執行的下一條指令的位址。
記憶體指針:包括程式代碼和程序相關資料的指針,還有和其他程序共享的記憶體塊的指針
上下文資料:程序執行時處理器的寄存器中的資料。
I/O狀态資訊:包括顯示的I/O請求,配置設定給程序的I/O裝置和被程序使用的檔案清單。
程序的幾種通信方式
管道( pipe ):
管道是一種半雙工的通信方式,資料隻能單向流動,而且隻能在具有親緣關系的程序間使用。程序的親緣關系通常是指父子程序關系。
有名管道 (named pipe) :
有名管道也是半雙工的通信方式,但是它允許無親緣關系程序間的通信。
信号量( semophore ) :
信号量是一個計數器,可以用來控制多個程序對共享資源的通路。它常作為一種鎖機制,防止某程序正在通路共享資源時,其他程序也通路該資源。是以,主要作為程序間以及同一程序内不同線程之間的同步手段。
消息隊列( message queue ) :
消息隊列是由消息的連結清單,存放在核心中并由消息隊列辨別符辨別。消息隊列克服了信号傳遞資訊少、管道隻能承載無格式位元組流以及緩沖區大小受限等缺點。
信号 ( sinal ) :
信号是一種比較複雜的通信方式,用于通知接收程序某個事件已經發生。
共享記憶體( shared memory ) :
共享記憶體就是映射一段能被其他程序所通路的記憶體,這段共享記憶體由一個程序建立,但多個程序都可以通路。共享記憶體是最快的 IPC 方式,它是針對其他程序間通信方式運作效率低而專門設計的。它往往與其他通信機制,如信号兩,配合使用,來實作程序間的同步和通信。
套接字( socket ) :
套解口也是一種程序間通信機制,與其他通信機制不同的是,它可用于不同及其間的程序通信。
線程同步的幾種方式及生産者消費者模型
- 臨界區:通過對多線程的串行化來通路公共資源或一段代碼,速度快,适合控制資料通路。在任意時刻隻允許一個線程對共享資源進行通路,如果有多個線程試圖通路公共資源,那麼在有一個線程進入後,其他試圖通路公共資源的線程将被挂起,并一直等到進入臨界區的線程離開,臨界區在被釋放後,其他線程才可以搶占。
- 互斥量:采用互斥對象機制。 隻有擁有互斥對象的線程才有通路公共資源的權限,因為互斥對象隻有一個,是以能保證公共資源不會同時被多個線程通路。互斥不僅能實作同一應用程式的公共資源安全共享,還能實作不同應用程式的公共資源安全共享
- 信号量:它允許多個線程在同一時刻通路同一資源,但是需要限制在同一時刻通路此資源的最大線程數目
-
事 件: 通過通知操作的方式來保持線程的同步,還可以友善實作對多個線程的優先級比較的操作
生産者消費者模型及源代碼見收藏。