進程(Process)是具有一定獨立功能的程式關於某個資料集合上的一次運行活動,是系統進行資源分派和調度的一個獨立單位。程式只是一組指令的有序集合,它本身沒有任何啟動並執行含義,只是一個靜態實體。而進程則不同,它是程式在某個資料集上的執行,是一個動態實體。它因建立而產生,因調度而運行,因等待資源或事件而被處於等待狀態,因完成任務而被撤消,反映了一個程式在一定的資料集上啟動並執行全部動態過程。
線程(Thread)是進程的一個實體,是CPU調度和指派的基本單位。線程不能夠獨立執行,必須依存在應用程式中,由應用程式提供多個線程執行控制。
線程和進程的關係是:線程是屬於進程的,線程運行在進程空間內,同一進程所產生的線程共用同一記憶體空間,當進程退出時該進程所產生的線程都會被強制退出並清除。線程可與屬於同一進程的其它線程共用進程所擁有的全部資源,但是其本身基本上不擁有系統資源,只擁有一點在運行中必不可少的資訊(如程式計數器、一組寄存器和棧)。
根據進程與線程的設定,作業系統大致分為如下類型:
1、單進程、單線程:MS-DOS大致是這種作業系統;
2、多進程、單線程:多數UNIX(及類Unix的Linux)是這種作業系統;
3、多進程、多線程:Windows NT(以及基於NT核心的Windows 2000、XP等)、Solaris 2.x和OS/2都是這種作業系統;
4、單進程、多線程:vxWorks就是這種作業系統。vxWorks只有一個進程(記憶體空間和資源分派),其任務的概念與線程大致相當,所有任務之間共用記憶體和其它資源。
vxWorks由一個體積很小的核心及一些可以根據需要進行定製的系統模組組成。vxWorks 核心最小為 8KB,即便加上其它必要模組,所佔用的空間也很小,且不失其即時、多任務的系統特徵。vxWorks的核心主要包括:
1、多任務:為滿足真實世界事件的非同步性,現代作業系統需提供多任務支援,由系統核心分配CPU給多個任務並發執行。如果是單CPU,則執行方式實質是宏觀並行、微觀串列;
2、任務調度:真實世界的事件具有繼承的優先順序,當一個高優先順序的任務變為可執行態,它會立即搶佔當前正在啟動並執行較低優先順序的任務,vxWorks對這種優先順序搶佔調度(Preemptive Priority Scheduling)提供了支援。同時,vxWorks也支援同優先順序任務間的時間片輪轉調度(Round-Robin Scheduling);
3、任務間的通訊與同步:在一個即時系統中,系統必須提供多個任務間快速且功能強大的通訊機制,並提供為了有效地共用不可搶佔的資源或臨界區所需的同步機制;
4、任務與中斷之間的通訊:許多外設以中斷方式與CPU通訊,我們不宜在中斷服務程式(ISR)中進行過多的處理,通常將相應處理交給特定任務去完成。
相關的具體解釋如下:
硬體中斷處理,硬體產生中斷,統治系統調用相應的中斷曆程(ISR),位是系統得到儘快的響應,ISR在它自己獨立的上下文和堆棧中運行,它的優先順序高於任何任務優先順序。
中斷延遲(Interrupt Latency),中斷延遲是指從硬體中斷髮生到開始執行中斷處理常式第一條指令之間的這段時間。
優先順序驅動(Priority-Driven),優先順序驅動是指多任務系統中,當前運行任務總是具有最高優先順序的就緒任務。
多任務調度分為兩種方式:優先搶佔和輪轉調度(Preemptive Priority,Round-Robin Scheduling)。優先搶佔(Preemptive Priority):每一個任務都有一個優先順序,系統核心保證優先順序最高的任務運行於CPU。如果有任務優先順序高於當前的任務優先順序,系統立刻儲存當前任務的上下文,切換到優先順序高的上下文;搶佔(Preemptive):搶佔是指當系統處於核心態運行時,允許任務的重新調度。換句話說就是指正在執行的任務可以被打斷,讓另一個任務運行。搶佔提高了應用對非同步事件的響應效能力。作業系統核心可搶佔,並不是說任務調度在任何時候都可以發生。例如當一個任務正在通過一個系統調用訪問共用資料時,重新調度和中斷都被禁止。
任務上下文(Task Context):任務上下文是指任務啟動並執行環境。例如,針對x86的CPU,任務上下文可包括程式計數器、堆棧指標、通用寄存器的內容。
環境切換(Context Switching):多任務系統中,環境切換是指CPU的控制權由運行任務轉移到另外一個就緒任務時所發生的事件,當前運行任務轉為就緒(或者掛起、刪除)狀態,另一個被選定的就緒任務成為當前任務。環境切換包括儲存當前任務的運行環境,恢複將要運行任務的運行環境。內容相關的內容依賴於具體的CPU。
輪轉調度(Round-Robin Scheduling):使所有相同優先順序,狀態為ready的任務公平分享CPU(分配一定的時間間隔,使個任務輪流享有CPU)。系統由256個優先順序,從0到255,0為最高,255為最低. 任務在被建立時設定了優先順序.也可用taskPrioritySet ( ) 來改變任務優先順序。
任務的主要狀態包括READY,PEND,DELAY,SUSPEND,各狀態輪轉如下:
ready-------->pended -----------semTake()/msgQReceive()-其他任務
ready-------->delayed-----------taskDelay()
ready-------->suspended---------taskSuspend()
pended------->ready-------------semaGive()/msgQSend()-其他任務
pended------->suspended---------taskSuspend()
delayed------>ready-------------expired delay
delayed------>suspended---------taskSuspend()
suspended---->ready-------------taskResume()/taskActivate()
suspended---->pended------------taskResume()
suspended---->delayed-----------taskResume()
輪轉調度 (Round-Robin):輪轉調度可以擴充到優先搶佔方式中,當多個任務優先順序相同的情況下,輪轉調度演算法使任務按平等的時間片運行於CPU,共用CPU.避免一個任務長時間佔用 CPU,而導致其他任務不能運行.可以用 kernelTimeSlice() 來定義時間長度.taskLock ( )和 taskUnlock ( ) 用來取消優先搶佔方式和恢複優先搶佔方式.注意: 一個任務可以調用taskDelete ( ) 刪除另一個任務,但是如果一個當前正在啟動並執行任務被刪除後,該任務的記憶體沒有釋放,而其他任務不知道,依然在等待,結果導致系統stop.用 taskSafe ( ) 和 taskUnsafe ( ) 來保證正在啟動並執行任務不被刪除.用法如下:
taskSafe (); semTake (semId, WAIT_FOREVER); .. .critical region . semGive (semId);semGive (semId); taskUnsafe (); . .critical region . semGive (semId);semGive (semId); taskUnsafe ();
tasklock()和和 taskUnlock()用來取消優先搶佔方式和恢複優先搶佔方式。
下面介紹下任務間的同步和進程間協調:
訊號量作為任務間同步和互斥的機制。在 wind 核中有幾種類型的訊號量,它們分別針對不同的應用需求:二進位訊號量、計數訊號量、互斥訊號量和 POSIX 訊號量。所有的這些訊號量是快速和高效的,它們除了被應用在開發設計過程中外,還被廣泛地應用在VxWorks 高層應用系統中。對於處理序間通訊,wind 核也提供了諸如訊息佇列、管道、通訊端和訊號等機制。
任務間的同步和進程間協調的幾種方式:
記憶體共用(Shared Memory),對簡單的資料共用而言.
訊號量(Semaphore),基本的互斥和同步.
訊息佇列(Message queues)和管道(Pipe),單個CPU中,任務間的資訊傳遞.
套結字(Socket)和遠程調用(Remote procedure calls),相對於網路任務間的通訊.
訊號(Signals),出錯處理(Exception handling).
記憶體共用(Shared Memory)
任務間通訊最通常的方式是通過共用的資料結構進行通訊,因為所有VxWorks的任務存在於一個單一的線性地址空間,任務間共用資料。全域變數、線性隊列、環形隊列、鏈表、指標都可被運行在不同內容相關的代碼所指向。
互斥(Mutual Exclusion)
互斥是用來控制多任務對共用資料進行串列訪問的同步機制。在多任務應用中,當兩個或多個任務同時訪問共用資料時,可能會造成資料破壞。互斥使它們串列地訪問資料,從而達到保護資料的目的.
解決互斥的幾種方法:
1. 關閉中斷的方法(intLock): 能解決任務和中斷ISR之間產生的互斥.
funcA () { int lock = intLock(); . . critical region that cannot be interrupted . intUnlock (lock); }
但在即時系統中採取這個辦法會影響系統對外部中斷及時響應和處理的能力.
2. 關閉系統優先順序(taskLock): 關閉系統優先順序,這樣在當前任務執行時,除了中斷外,不會有其他優先順序高的任務來搶佔CPU,影響當前程式運行.
funcA () { taskLock (); . . critical region that cannot be interrupted . taskUnlock (); }
這種方法阻止了高優先順序的任務搶先運行,在即時系統中也是不適合的,除非關閉優先順序的時間特別短.
訊號量(Semaphore): 訊號量是解決互斥和同步協調進程最好的方法。VxWorks訊號量提供最快速的任務間通訊機制,它主要用於解決任務間的互斥和同步。針對不同類型的問題,有以下三種訊號量:
1、二進位訊號量(binary) 使用最快捷、最廣泛,主要用於同步或互斥;
2、互斥訊號量(mutual exclusion) 特殊的二進位訊號量,主要用於優先順序繼承、安全刪除和回溯;
3、計數器訊號量(counting) 和二進位訊號量類似,保持訊號量被釋放(gaven)的次數。主要用於保護一個資源的多個常式(multiple instances of a resource)
訊號量控制,函數介紹:
semBCreate( ) 分配並初始化一個二進位訊號量
semMCreate( ) 分配並初始化一個互斥訊號量
semCCreate( ) 分配並初始化一個計數訊號量
semDelete( ) 終止一個自由的訊號量
emTake( ) 佔有一個訊號量
semGive( ) 釋放一個訊號量
semFlush( ) 解鎖所有等待訊號量的任務
semBCreate( ), semMCreate( ), and semCCreate( )返回一個訊號量ID作為其它後續任務使用該訊號量的的控制代碼。當一個訊號量被建立,它的隊列(queue)類型就被確定。等待訊號量的任務隊列以優先順序的高低排列(SEM_Q_PRIORITY),或者一先到先得的方式排列(SEM_Q_FIFO).
當一個Semaphore建立時,指定了任務隊列的種類。
semBCreat( SEM_Q_PRIORITY, SEM_FULL), SEM_Q_PRIORITY 指明處於等待狀態的任務在等待隊列中以優先順序的順序排列
semBCreat(SEM_Q_FIFO,SEM_FULL), SEM_Q_FIFO指明處於等待狀態的任務在等待隊列中以先進先出的順序排列
互斥進程(Mutual Exclusion)
互斥訊號量有效內鎖對共用資源的進入,與屏蔽中斷(disabling interrupts)和優先順序鎖定(preemptive locks)相比,二進位訊號量將互斥的範圍限制在僅與其有關的資源上。從技術上說,建立一個訊號量來保護(guarding)資源。訊號量初始化位可用的(FULL),當一個Semaphore建立時,指定了這個semaphore是用在解決互斥還是用來同步任務
semBCreat( SEM_Q_FIFO, SEM_FULL) , SEM_FULL 指明用於任務間互斥.
SEM_ID semMutex;semMutex = semBCreate (SEM_Q_PRIORITY, SEM_FULL)