計算機所有可執行的軟體,通常也包括作業系統,被組織成若干順序程序,簡稱程序。乙個程序就是乙個正在執行程式的例項
單核cpu也就是單個核心的cpu,每次只能執行乙個程序,由於cpu在各程序之間快速切換,所以每個程序所執行的時間是不確定的。
舉個例子:
假設你在看著食譜做美食,那麼你就相當於cpu,食譜就是程式,而做美食的材料就是輸入資料,程序就是,你在閱讀食譜取食材以及製作美食的這一系列動作,假設你在做美食時候突然來了個**,你可能會先熄火,然後腦海裡知道自己現在做到哪個位置(儲存當前狀態),然後去接**,處理完了後,你可能才回來廚房想想剛才做到**了,然後繼續之前繼續做
乙個程序就是某種型別的乙個活動,它有程式、輸入、輸出以及狀態。單個處理器可以被多個程序共享,cpu使用了某種排程演算法決定何時停止乙個程序的工作,並且轉向另乙個程序提供服務。
程序的建立:有四種主要的事件
1、系統初始化
前台程序
守護程序
2、正在執行的程式執行了建立程序的系統呼叫
3、使用者請求建立乙個新程序
4、乙個批處理作業的初始化
程序的終止
1、正常退出
2、出錯退出
3、嚴重錯誤
4、被其他程序給殺死
只可以有乙個父程序,但可以有零個或者多個子程序
程序有三種狀態:
執行態,就緒態,阻塞態
為了實現程序模型,作業系統維護著一張**(乙個結構陣列)即程序表,每個程序占用乙個程序表的乙個項,這張表包含了許多資訊,比如程式計數器,堆疊指標,記憶體分配狀況,等等從而保證了該程序被斷掉後重新啟動的時候,能夠儲存之前的資訊。
為什麼需要執行緒?
首先,有了執行緒,我們可以不必考慮終端、定時器、和上下文的切換只需考慮並行程序。其次,執行緒比程序更加輕量級,速度會比用程序效率要提高很多。
每個單核處理器在某個時刻也是只能夠執行乙個執行緒的,這和程序是一樣的,執行緒是cpu處理的基本單位,我們前面討論的程序,是程序單執行緒模型。
同樣的,執行緒也是有阻塞態、執行態、就緒態。
為了實現可移植的執行緒程式,ieee在ieee標準中定義了執行緒的標準,它定義的執行緒包叫做pthread
實現執行緒包有兩種方法,第一種把整個執行緒包放在使用者空間
從核心的角度上管理的就是單執行緒程序的模型,這樣子儘管系統不支援執行緒,也可以進行實現
用c語言實現
#include#include#include#define number 10
void *hello(void *id)
int main()
}return 0;
}
在使用者空間管理執行緒的時候會建立乙個執行時的系統,由這個系統進行管理,每個程序都需要其專用的執行緒表,用來跟蹤該程序中的執行緒。這些表和程序表相似,不過它僅僅記錄的是各個執行緒的屬性,如每個執行緒的程式計數器,堆疊指標,暫存器和狀態。因為切換執行緒的時候不需要陷入到核心空間,不需要有上下文的切換,也不需要對記憶體快取記憶體進行重新整理,這就使得執行緒排程非常快捷。
使用者執行緒還有乙個優點,允許每個程序有自己定製的排程演算法,這樣子就有乙個很好的可擴充套件性
如果某個執行緒阻塞了,就會導致整個程序的阻塞
在核心中實現執行緒
此時不再需要執行時的系統了,另外,每個程序中也沒有執行緒表,核心中有用來記錄系統中所有執行緒的執行緒表了,當某個執行緒希望建立乙個新的執行緒的時候,就會進行乙個系統的呼叫,這個系統呼叫通過對執行緒表的更新完成執行緒建立的工作。
核心的執行緒表裡儲存了每個執行緒的資訊,這些資訊和在使用者空間中的執行緒是一樣的,但是現在儲存在核心中
由於在核心中建立執行緒的代價比較大,所以某些系統會採取一種方式:**執行緒,當某個執行緒被撤銷的時候,就標記為不可執行的,但是其核心資料的結構沒有收到影響。再次建立乙個新的執行緒的時候,就把這個執行緒給重新啟動就可以了,這樣子可以減少多次系統呼叫來開闢新的執行緒
混合實現
使用核心級的執行緒,然後將使用者級的執行緒與某些或者全部核心執行緒多路復用,採取這種方式:開發人員就可以決定有多少個核心級的執行緒和多少個使用者級執行緒即使多路復用,這個模型可以帶來最大的靈活度
比如說乙個購票系統:
程序a和程序b,此時:程序a去買票(一共十張):首先讀出票數,把票數減一,然後把減一後的資料放回去
假設在第二個步驟的時候發生cpu 的切換,程序b去讀票數,那麼去讀的時候此時票數還是10,然後進行減一後,放回去,再切回執行緒a,放回去,這裡就有個問題:同一張票給了兩個程序去賣了!這明顯是不科學的。
為了有效避免程序的競爭問題這裡需要做的就是互斥,那麼什麼是互斥呢?就是a在訪問的時候,禁止b訪問,這樣子就能夠進行乙個有效的防止競爭了。
這裡面設計很多種方法:
遮蔽中斷:每個程序在剛剛進入臨界區後立刻遮蔽所有中斷,並在就有離開之前再開啟終端,遮蔽中斷後,時鐘中斷也會被遮蔽,cpu只有發生時鐘中斷或者其他中斷才會進行切換,這樣子,在遮蔽中斷之後,cpu將不會進行切換
鎖變數:共享乙個變數(鎖),初始值為0,當乙個程序進入臨界區的時候,就測試這把鎖,如果該鎖為0則程序把鎖設定為1,然後進入,如果進入的時候鎖的值為1,則等待,當出去臨界區的時候再把鎖的值改為0
嚴格輪換法:
嚴格輪換法同樣也是針對乙個臨界區設定乙個變數,假設為turn。以兩個程序為例子:
當turn為0時,process 0才能能進入臨界區,否則等待。等process 0離開臨界區後,將turn設定為1.
當turn為1時,process 1才能進入臨界區,否則等待。等process 1離開臨界區後,將turn設定為0.
執行緒和程序
標準的定義是 程序是執行緒的容器,乙個程序可於乙個或者多個執行緒,它是系統分配資源的基本單位 同乙個程序下,執行緒共享位址空降 已經開啟的檔案 訊號處理函式 報警訊號和其他,執行緒自己只保留程式計數器和棧。但是很遺憾的,這個只是教科書上的定義,實際情況是每個作業系統實現的作業系統特性不同,實現的方法...
程序和執行緒
乙個程序就是當前正在執行的乙個程式,包括程式的暫存器 程式計數器和變數的當前值。不同的程序擁有不同的位址空間。而執行緒可以理解為是程序中的控制流。同乙個程序內也就是說在同乙個位址空間內可以有多個控制流。也就是可以有多個線 程,他們共享位址空間。我們通常將程序視為是資源的集合,程序中有程式的正文 資料...
執行緒和程序
對於求職者,在面試的時候大多都會被問到 你對多執行緒了解麼?給我講講執行緒和程序的區別吧。在unix中,乙個程序可以理解為執行緒 位址空間 檔案描述符 資料,道破現實,其實就相當於老闆和員工,老闆就是程序,員工就是執行緒。老闆需要僱傭若干員工 執行緒 還要有辦公樓 位址空間 還要有若干的辦公裝置 檔...