OS學習筆記二: 程式執行緒模型
一、程式基本概念
1、併發環境與併發程式
- 併發環境:一段時間 間隔 內,單處理器上有兩個或兩個以上的程式 同時 處於開始執行但尚未結束的狀態 ,並且 次序不是事先確定的
- 併發程式:在併發環境中執行的程式
2、程式的定義
定義:Process(對CPU 的抽象) 程式是具有獨立功能的程式關於 某個資料集合上 的一次執行活動 ,是系統進行 資源分配和 排程 的獨立單位又稱 任務(Task or Job )
程式的一次執行過程
是正在執行程式的抽象
將一個 CPU 變幻成多個虛擬的 CPU
系統資源以程式為單位分配,如記憶體、檔案、 ……每個具有獨立的地址空間
作業系統將 CPU 排程
3、程式控制塊 PCB
PCB :Process Control Block
又稱 程式描述符、程式屬性
作業系統用於管理控制程式的一個專門資料結構
記錄程式的各種屬性,描述程式的動態變化過程
PCB 是系統感知程式存在的唯一標誌
- 程式與PCB 是一一對應的
程式 表:所有程式的PCB
4、程式描述資訊
程式識別符號(process ID),唯一,通常是一個整數
程式名,通常基於可執行檔名,不唯一
使用者識別符號(user ID)
程式組關係
5、程式控制資訊
當前狀態
優先順序(priority)
程式碼執行入口地址
程式的磁碟地址
執行統計資訊(執行時間、頁面排程)
程式間同步和通訊
程式的佇列指標
程式的訊息佇列指標
6、所擁有的資源和使用情況
虛擬地址空間的狀況
開啟檔案列表
7、CPU 現場資訊
暫存器值(通用暫存器、程式計數器PC、程式狀態字PSW、棧指標)
指向該程式頁表的指標
二、程式狀態及狀態轉換
1、七狀態程式模型
2、程式佇列
作業系統為每一類程式建立一個或多個佇列
佇列元素為PCB
伴隨程式狀態的改變,其PCB 從一個佇列進入另一個佇列
多個等待佇列等待的事件不同
就緒佇列也可以多個
單CPU 情況下,執行佇列中只有一個程式
三、程式控制
1、程式控制
程式控制操作完成程式各狀態之間的轉換,由具有特定功能的 原語 完成
程式建立原語
程式撤消原語
阻塞原語
喚醒原語
掛起原語
啟用原語
改變程式優先順序
……
原語(primitive)完成某種特定功能的一段程式,具有不可分割性或不可中斷性
即 原語的執行必須是連續的,在執行過程中不允許被中斷
2、程式的建立
給新程式分配一個唯一標識以及程式控制塊
為程式分配地址空間
初始化程式控制塊
設定預設值 ( 如: 狀態為 New ,…)
設定相應的佇列指標
如: 把新程式加到就緒佇列連結串列中
UNIX:fork/exec
WINDOWS:CreateProcess
3、程式的撤銷
結束程式
收回程式所佔有的資源
關閉開啟的檔案、斷開網路連線、 回收 分配的記憶體、……
撤消該程式的PCB
UNIX:exit
WINDOWS:TerminateProcess
4、程式阻塞
處於執行狀態的程式,在其執行過程中期待某一事件發生,如 等待鍵盤輸入、等待磁碟資料傳輸完成、等待其它程式傳送訊息 ,當被等待的事件未發生時,由 程式自己執行阻塞原語 ,使自己由執行態變為阻塞態。
UNIX:wait
WINDOWS:WaitForSingleObject
5、UNIX的幾個程式控制操作
fork() 通過 複製呼叫程式 來建立新的程式,是最基本的程式建立過程
exec() 包括一系列系統呼叫,它們都是通過用一段新的程式程式碼覆蓋原來的地址空間,實現程式 執行程式碼的轉換
wait() 提供初級程式同步 操作 ,能使一個程式等待另外一個程式的結束
exit() 用來終止一個程式的執行
6、UNIX的fork實現
為子程式分配一個空閒 的程式 描述符
proc 結構
分配給子程式唯一標識 pid
以一次一頁的方式複製父程式地址空間(Linux 採用了寫時
複製技術COW 加快建立程式Copy-On-Write,即建立時將父程式把地址空間的指標傳遞給子程式,再把地址空間設定為只讀,當子程式想往地址空間寫東西的時候,作業系統再為子程式開闢一塊空間把相應的內容放進去)從父程式處繼承共享資源,如開啟的檔案和當前工作目錄 等
將子程式的狀態設為就緒,插入到就緒佇列
對子程式返回識別符號 0
向父程式返回子程式的 pid
示意程式碼:
#include <sys/types.h>
#include <stdio.h>
#include <unistd.h>
void main( int argc, char *argv[] )
{
pid_t pid;
pid = fork(); /* 建立一個子程式 */
if ( pid < 0 ) /* 出錯 */
{
fprintf( stderr, “ fork failed ” );
exit( -1 );
}else if ( pid == 0 ) /* 子 程式 */
{
execlp( “ / bin / ls ”, “ ls ”, NULL );
}else { /* 父程式 */
wait( NULL ); /* 父 程式等待子程式結束 */
printf( “ child complete ” );
exit( 0 );
}
}
四、深入理解程式概念
1、程式層次結構
UNIX 程式 家族 樹 :init 為根
Windows:地位相同
2、程式與程式的區別
程式更 能準確刻畫併發,而程式不能
程式 是靜態的,程式是動態的
程式有 生命週期的, 有誕生有消亡 ,是短暫 的;而程式是相對長久的
一個程式可對應多個程式
程式具有建立其他程式的 功能
3、程式的地址空間
作業系統給每個程式都分配了一個地址空間
int myval;
int main( int argc, char *argv[] )
{
myval = atoi( argv[1] );
while ( 1 )
printf( “ myval is % d, loc 0x % lx \ n ”,
myval, (long) &myval );
}
同時 執行兩個 Myval 程式,會輸出什麼?
輸出的地址是相對地址 或者說是邏輯地址或者虛擬地址,所以才會出現變數不同,但地址相同的情況(因為兩次執行是在不同的程式中的)。
4、上下文(CONTEXT)切換
將CPU 硬體狀態從一個程式換到另一個程式的過程稱為 上下文 切換
程式 執行時 ,其硬體狀態儲存在CPU 上 的暫存器中
- 暫存器:程式計數器、程式狀態暫存器、棧指標、通用暫存器、其他控制暫存器的值
程式不執行時,這些暫存器的值儲存在程式控制塊
- PCB 中; 當作業系統要 執行一個新的程式時,將PCB 中 的相關值 送到對應的暫存器 中
五、執行緒的引入
1、執行緒的開銷小
建立 一個新執行緒花費時間少(撤銷亦如此)
兩 個 執行緒切換 花費時間少
執行緒 之間相互通訊無須呼叫核心(同一程式內的執行緒共享記憶體和檔案)
2、執行緒的屬性
有標示符ID
有狀態及狀態轉換 → 需要提供一些操作
不執行時需要儲存的上下文
有上下文環境:程式計數器等暫存器
有自己的棧和棧指標 √
共享所在程式的地址空間和其他資源
可以建立、撤消另一個執行緒
- 程式開始是以一個單執行緒程式方式執行的
六、執行緒的實現機制
1、使用者級執行緒
- 在使用者空間建立 執行緒庫:提供一組管理執行緒的過程
- 執行時系統:完成執行緒的 管理工作(操作、執行緒表)
- 核心管理的還是程式,不知道 執行緒的存在
- 執行緒 切換不 需要核心態特權
- 例子:UNIX
使用者級執行緒小結:
優點:
- 執行緒切換快
- 排程演算法是應用程式特定的
- 使用者級執行緒可執行在任何作業系統上(只需要實現執行緒庫)
- 缺點:
- 核心只將處理器分配給程式,同一程式中的兩個執行緒不能同時執行於兩個處理器上
- 大多數系統呼叫是阻塞的,因此,由於核心阻塞程式,故程式中所有執行緒也被阻塞
2、 核心級執行緒
- 核心管理所有執行緒管理,並嚮應用程式提供API介面
- 核心維護程式和執行緒的上下文
- 執行緒的切換需要核心支援
- 以執行緒為基礎進行排程
- 例子:Windows
3、混合模型
- 執行緒建立在使用者空間完成
- 執行緒排程等在核心態完成
- 例子:Solaris
4、可再入程式(可重入)
可被多個程式同時呼叫的程式,具有下列性質:
1、它是純程式碼的,即在執行過程中自身不改變;
2、呼叫它的程式應該提供資料區
個人微信公眾號:
作者:jiankunking 出處:http://blog.csdn.net/jiankunking
相關文章
- Linux程式執行緒學習筆記Linux執行緒筆記
- Dubbo學習筆記(三) RPC核心原理和執行緒模型筆記RPC執行緒模型
- Python學習筆記 - 多執行緒Python筆記執行緒
- Java 多執行緒學習筆記Java執行緒筆記
- 程式間通訊(linux程式與執行緒學習筆記)Linux執行緒筆記
- 多執行緒筆記 二執行緒筆記
- 好程式設計師大資料學習路線分享執行緒學習筆記二程式設計師大資料執行緒筆記
- Python學習筆記|Python之執行緒Python筆記執行緒
- Java多執行緒學習筆記(自用)Java執行緒筆記
- Java併發程式設計學習筆記----執行緒池Java程式設計筆記執行緒
- Redis基礎知識(學習筆記6--執行緒IO模型)Redis筆記執行緒模型
- Python筆記二之多執行緒Python筆記執行緒
- 共享記憶體對映(linux程式與執行緒學習筆記)記憶體Linux執行緒筆記
- 多執行緒學習(二)執行緒
- C# 多執行緒學習筆記 – 1C#執行緒筆記
- Thinking in Java---多執行緒學習筆記(2)ThinkingJava執行緒筆記
- 深入學習redis 的執行緒模型Redis執行緒模型
- redis執行緒模型-學習小結Redis執行緒模型
- os/signal學習筆記筆記
- java併發筆記之java執行緒模型Java筆記執行緒模型
- (三)Java併發學習筆記–執行緒封閉Java筆記執行緒
- C# 使用執行緒池佇列(學習筆記)C#執行緒佇列筆記
- Thinking in Java--Java多執行緒學習筆記(1)ThinkingJava執行緒筆記
- Java 併發程式設計學習筆記 05 :如何暫停執行緒?Java程式設計筆記執行緒
- Netty 框架學習 —— EventLoop 和執行緒模型Netty框架OOP執行緒模型
- 程式和執行緒模型執行緒模型
- 好程式設計師大資料學習路線分享多執行緒學習筆記程式設計師大資料執行緒筆記
- Adnroid原始碼學習筆記:Handler 執行緒間通訊原始碼筆記執行緒
- Java多執行緒學習筆記(六) 長樂未央篇Java執行緒筆記
- 多執行緒筆記執行緒筆記
- 多執行緒學習(二)CountDownLunch與CyclicBarrier執行緒
- React學習手冊-React執行機制筆記(二)React筆記
- python 程式、執行緒 (二)Python執行緒
- C#多執行緒學習(二) 如何操縱一個執行緒C#執行緒
- Python學習之程式和執行緒Python執行緒
- 【Python3學習筆記】之【Python高階——多執行緒】Python筆記執行緒
- 二十:從庫MTS多執行緒並行回放(二)(筆記)執行緒並行筆記
- iOS 多執行緒筆記iOS執行緒筆記
- 多執行緒筆記 一執行緒筆記