CPU調度單位是線程而不是進程,調度器據以排序的是每個線程的優先級。如果線程A和線程B具有相同優先級,調度器會挑選等待時間比較久的那個。
一、線程調度
調度器會彈性調整線程優先級,以強化系統的反應能力,並且避免任何一個線程一直未能接受CPU的潤澤。例如:一般的線程優先級是7,如果它被切換到前台,調度系統可能暫時地把它調升到8或9或更高。對於那些有著輸入消息等待被處理的線程,調度系統也會暫時調高其優先級。
二、線程產生
以::CreateThread產生一個線程,並指定一個線程函數,它就是一個worker thread,除非在它的生命中接觸到了輸入消息,這時候它應該有一個消息循環,以抓取消息,於是該線程就變為UI thread。
CWinThread對象代表一個線程本身。每當你需要一個線程時,不應該在MFC程序中直接調用::CreateThread或_beginthreadex,應該先產生一個CWinThread對象,再調用其成員函數CreateThread或全局函數AfxBeginThread。CWinThread::CreateThread或AfxBeginThread內部調用了beginthreadex。
CWinThread::CreateThread和AfxBeginThread不只是::CreateThread的一層封裝,更做了一些application framework所需的內部數據初始化工作,並確保使用正確的C runtime library版本。
1、產生一個Worker Thread
CWinThread *pThread = AfxBeginThread(ThreadFunc, ¶m); UINT ThreadFunc(LPVOID param) { }
2、產生一個UI Thread
UI Thread不能夠由一個函數來代表,應該先從CWinThread派生出一個自己的類,再調用AfxBeginThread產生一個CWinThread對象。
注意:
(1)線程函數是由系統調用的,也就是一個callback函數,不容許有this指針參數。所以任何一般的C++類成員函數都不能拿來當線程函數,它必須是個全局函數或是個C++類的static成員函數。
(2)比較好的做法是把所有UI操作都集中在主線程,其他的“純運算操作”才考慮交給Worker Thread去做。
三、線程結束
Worker Thread的生命就是線程函數本身,函數一旦return,線程結束。或者線程函數調用AfxEndThread結束一個線程。UI Thread因為有消息循環的關系,必須在消息隊列中放一個WM_QUIT,才能結束線程。或在線程的任何一個函數中調用AfxEndThread也可以結束線程。
AfxEndThread內部調用_endthreadex,由它結束線程。
四、線程與同步控制
Windows系統提供了四種同步化機制,MFC也提供了四個對應的類。
(1)Critical Section(關鍵區域)。
(2)Semaphore(信號量)。
(3)Event(事件)。
(4)Mutex(互斥器)。