vxWorks多任务编程初探-上
??????? 線程(Thread)是進程的一個實體,是CPU調(diào)度和分派的基本單位。線程不能夠獨立執(zhí)行,必須依存在應用程序中,由應用程序提供多個線程執(zhí)行控制。
?????? 線程和進程的關(guān)系是:線程是屬于進程的,線程運行在進程空間內(nèi),同一進程所產(chǎn)生的線程共享同一內(nèi)存空間,當進程退出時該進程所產(chǎn)生的線程都會被強制退出并清除。線程可與屬于同一進程的其它線程共享進程所擁有的全部資源,但是其本身基本上不擁有系統(tǒng)資源,只擁有一點在運行中必不可少的信息(如程序計數(shù)器、一組寄存器和棧)。
?????? 根據(jù)進程與線程的設(shè)置,操作系統(tǒng)大致分為如下類型:
?????????? 1、單進程、單線程:MS-DOS大致是這種操作系統(tǒng);
????? ?? ? 2、多進程、單線程:多數(shù)UNIX(及類Unix的Linux)是這種操作系統(tǒng);
????? ?? ? 3、多進程、多線程:Windows NT(以及基于NT內(nèi)核的Windows 2000、XP等)、Solaris 2.x和OS/2都是這種操作系統(tǒng);
????? ?? ? 4、單進程、多線程:vxWorks就是這種操作系統(tǒng)。vxWorks只有一個進程(內(nèi)存空間和資源分配),其任務的概念與線程大致相當,所有任務之間共享內(nèi)存和其它資源。
??????? vxWorks由一個體積很小的內(nèi)核及一些可以根據(jù)需要進行定制的系統(tǒng)模塊組成。vxWorks 內(nèi)核最小為 8KB,即便加上其它必要模塊,所占用的空間也很小,且不失其實時、多任務的系統(tǒng)特征。vxWorks的內(nèi)核主要包括:
??????? 1、多任務:為滿足真實世界事件的異步性,現(xiàn)代操作系統(tǒng)需提供多任務支持,由系統(tǒng)內(nèi)核分配CPU給多個任務并發(fā)執(zhí)行。如果是單CPU,則執(zhí)行方式實質(zhì)是宏觀并行、微觀串行;
??????? 2、任務調(diào)度:真實世界的事件具有繼承的優(yōu)先級,當一個高優(yōu)先級的任務變?yōu)榭蓤?zhí)行態(tài),它會立即搶占當前正在運行的較低優(yōu)先級的任務,vxWorks對這種優(yōu)先級搶占調(diào)度(Preemptive Priority Scheduling)提供了支持。同時,vxWorks也支持同優(yōu)先級任務間的時間片輪轉(zhuǎn)調(diào)度(Round-Robin Scheduling);
??????? 3、任務間的通訊與同步:在一個實時系統(tǒng)中,系統(tǒng)必須提供多個任務間快速且功能強大的通信機制,并提供為了有效地共享不可搶占的資源或臨界區(qū)所需的同步機制;
?????? 4、任務與中斷之間的通信:許多外設(shè)以中斷方式與CPU通信,我們不宜在中斷服務程序(ISR)中進行過多的處理,通常將相應處理交給特定任務去完成。
相關(guān)的具體解釋如下:
?????? 硬件中斷處理,硬件產(chǎn)生中斷,統(tǒng)治系統(tǒng)調(diào)用相應的中斷歷程(ISR),位是系統(tǒng)得到盡快的響應,ISR在它自己獨立的上下文和堆棧中運行,它的優(yōu)先級高于任何任務優(yōu)先級。
?????? 中斷延遲(Interrupt Latency),中斷延遲是指從硬件中斷發(fā)生到開始執(zhí)行中斷處理程序第一條指令之間的這段時間。
????? 優(yōu)先級驅(qū)動(Priority-Driven),優(yōu)先級驅(qū)動是指多任務系統(tǒng)中,當前運行任務總是具有最高優(yōu)先級的就緒任務。
??????? 多任務調(diào)度分為兩種方式:優(yōu)先搶占和輪轉(zhuǎn)調(diào)度(Preemptive Priority,Round-Robin Scheduling)。優(yōu)先搶占(Preemptive Priority):每一個任務都有一個優(yōu)先級,系統(tǒng)核心保證優(yōu)先級最高的任務運行于CPU。如果有任務優(yōu)先級高于當前的任務優(yōu)先級,系統(tǒng)立刻保存當前任務的上下文,切換到優(yōu)先級高的上下文;搶占(Preemptive):搶占是指當系統(tǒng)處于核心態(tài)運行時,允許任務的重新調(diào)度。換句話說就是指正在執(zhí)行的任務可以被打斷,讓另一個任務運行。搶占提高了應用對異步事件的響應性能力。操作系統(tǒng)內(nèi)核可搶占,并不是說任務調(diào)度在任何時候都可以發(fā)生。例如當一個任務正在通過一個系統(tǒng)調(diào)用訪問共享數(shù)據(jù)時,重新調(diào)度和中斷都被禁止。
?????? 任務上下文(Task Context):任務上下文是指任務運行的環(huán)境。例如,針對x86的CPU,任務上下文可包括程序計數(shù)器、堆棧指針、通用寄存器的內(nèi)容。
?????? 上下文切換(Context Switching):多任務系統(tǒng)中,上下文切換是指CPU的控制權(quán)由運行任務轉(zhuǎn)移到另外一個就緒任務時所發(fā)生的事件,當前運行任務轉(zhuǎn)為就緒(或者掛起、刪除)狀態(tài),另一個被選定的就緒任務成為當前任務。上下文切換包括保存當前任務的運行環(huán)境,恢復將要運行任務的運行環(huán)境。上下文的內(nèi)容依賴于具體的CPU。
?????? 輪轉(zhuǎn)調(diào)度(Round-Robin Scheduling):使所有相同優(yōu)先級,狀態(tài)為ready的任務公平分享CPU(分配一定的時間間隔,使個任務輪流享有CPU)。系統(tǒng)由256個優(yōu)先級,從0到255,0為最高,255為最低. 任務在被創(chuàng)建時設(shè)定了優(yōu)先級.也可用taskPrioritySet ( ) 來改變?nèi)蝿諆?yōu)先級。
任務的主要狀態(tài)包括READY,PEND,DELAY,SUSPEND,各狀態(tài)輪轉(zhuǎn)如下:
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()
輪轉(zhuǎn)調(diào)度 (Round-Robin):輪轉(zhuǎn)調(diào)度可以擴充到優(yōu)先搶占方式中,當多個任務優(yōu)先級相同的情況下,輪轉(zhuǎn)調(diào)度算法使任務按平等的時間片運行于CPU,共享CPU.避免一個任務長時間占用 CPU,而導致其他任務不能運行.可以用 kernelTimeSlice() 來定義時間長度.taskLock ( )和 taskUnlock ( ) 用來取消優(yōu)先搶占方式和恢復優(yōu)先搶占方式.注意: 一個任務可以調(diào)用taskDelete ( ) 刪除另一個任務,但是如果一個當前正在運行的任務被刪除后,該任務的內(nèi)存沒有釋放,而其他任務不知道,依然在等待,結(jié)果導致系統(tǒng)stop.用 taskSafe ( ) 和 taskUnsafe ( ) 來保證正在運行的任務不被刪除.用法如下:
tasklock()和和 taskUnlock()用來取消優(yōu)先搶占方式和恢復優(yōu)先搶占方式。
下面介紹下任務間的同步和進程間協(xié)調(diào):
信號量作為任務間同步和互斥的機制。在 wind 核中有幾種類型的信號量,它們分別針對不同的應用需求:二進制信號量、計數(shù)信號量、互斥信號量和 POSIX 信號量。所有的這些信號量是快速和高效的,它們除了被應用在開發(fā)設(shè)計過程中外,還被廣泛地應用在VxWorks 高層應用系統(tǒng)中。對于進程間通信,wind 核也提供了諸如消息隊列、管道、套接字和信號等機制。
任務間的同步和進程間協(xié)調(diào)的幾種方式:
內(nèi)存共享(Shared Memory),對簡單的數(shù)據(jù)共享而言.
信號量(Semaphore),基本的互斥和同步.
消息隊列(Message queues)和管道(Pipe),單個CPU中,任務間的信息傳遞.
套結(jié)字(Socket)和遠程調(diào)用(Remote procedure calls),相對于網(wǎng)絡(luò)任務間的通信.
信號(Signals),出錯處理(Exception handling).
內(nèi)存共享(Shared Memory)
任務間通信最通常的方式是通過共享的數(shù)據(jù)結(jié)構(gòu)進行通信,因為所有VxWorks的任務存在于一個單一的線性地址空間,任務間共享數(shù)據(jù)。全局變量、線性隊列、環(huán)形隊列、鏈表、指針都可被運行在不同上下文的代碼所指向。
互斥(Mutual Exclusion)
互斥是用來控制多任務對共享數(shù)據(jù)進行串行訪問的同步機制。在多任務應用中,當兩個或多個任務同時訪問共享數(shù)據(jù)時,可能會造成數(shù)據(jù)破壞。互斥使它們串行地訪問數(shù)據(jù),從而達到保護數(shù)據(jù)的目的.
解決互斥的幾種方法:
1. 關(guān)閉中斷的方法(intLock): 能解決任務和中斷ISR之間產(chǎn)生的互斥.
但在實時系統(tǒng)中采取這個辦法會影響系統(tǒng)對外部中斷及時響應和處理的能力.
2. 關(guān)閉系統(tǒng)優(yōu)先級(taskLock): 關(guān)閉系統(tǒng)優(yōu)先級,這樣在當前任務執(zhí)行時,除了中斷外,不會有其他優(yōu)先級高的任務來搶占CPU,影響當前程序運行.
這種方法阻止了高優(yōu)先級的任務搶先運行,在實時系統(tǒng)中也是不適合的,除非關(guān)閉優(yōu)先級的時間特別短.
信號量(Semaphore): 信號量是解決互斥和同步協(xié)調(diào)進程最好的方法。VxWorks信號量提供最快速的任務間通信機制,它主要用于解決任務間的互斥和同步。針對不同類型的問題,有以下三種信號量:
1、二進制信號量(binary) 使用最快捷、最廣泛,主要用于同步或互斥;
2、互斥信號量(mutual exclusion) 特殊的二進制信號量,主要用于優(yōu)先級繼承、安全刪除和回溯;
3、計數(shù)器信號量(counting) 和二進制信號量類似,保持信號量被釋放(gaven)的次數(shù)。主要用于保護一個資源的多個例程(multiple instances of a resource)
信號量控制,函數(shù)介紹:
semBCreate( ) 分配并初始化一個二進制信號量
semMCreate( ) 分配并初始化一個互斥信號量
semCCreate( ) 分配并初始化一個計數(shù)信號量
semDelete( ) 終止一個自由的信號量
emTake( ) 占有一個信號量
semGive( ) 釋放一個信號量
semFlush( ) 解鎖所有等待信號量的任務
semBCreate( ), semMCreate( ), and semCCreate( )返回一個信號量ID作為其它后續(xù)任務使用該信號量的的句柄。當一個信號量被創(chuàng)建,它的隊列(queue)類型就被確定。等待信號量的任務隊列以優(yōu)先級的高低排列(SEM_Q_PRIORITY),或者一先到先得的方式排列(SEM_Q_FIFO).
當一個Semaphore創(chuàng)建時,指定了任務隊列的種類。
semBCreat( SEM_Q_PRIORITY, SEM_FULL), SEM_Q_PRIORITY 指明處于等待狀態(tài)的任務在等待隊列中以優(yōu)先級的順序排列
semBCreat(SEM_Q_FIFO,SEM_FULL), SEM_Q_FIFO指明處于等待狀態(tài)的任務在等待隊列中以先進先出的順序排列
互斥進程(Mutual Exclusion)
互斥信號量有效的內(nèi)鎖對共享資源的進入,與屏蔽中斷(disabling interrupts)和優(yōu)先級鎖定(preemptive locks)相比,二進制信號量將互斥的范圍限制在僅與其有關(guān)的資源上。從技術(shù)上說,創(chuàng)建一個信號量來保護(guarding)資源。信號量初始化位可用的(FULL),當一個Semaphore創(chuàng)建時,指定了這個semaphore是用在解決互斥還是用來同步任務
SEM_ID semMutex;semMutex = semBCreate (SEM_Q_PRIORITY, SEM_FULL)
總結(jié)
以上是生活随笔為你收集整理的vxWorks多任务编程初探-上的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 18.QT-QPlainEdit 信号与
- 下一篇: 傅里叶变换与拉普拉斯变换