??????? 線程(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是用在解決互斥還是用來同步任務
SEM_ID semMutex;semMutex = semBCreate (SEM_Q_PRIORITY, SEM_FULL)