佛說,彼岸花,開一千年,落一千年,花葉永不相見。情不為因果,緣注定生死。
1 程序的組成:虛拟的位址空間,代碼,系統資源。
線程分類:使用者界面線程,主線程。舉例:CWinApp 就是一個使用者界面線程。
線程間通信的方式有兩種:1 全局變量 2 自定義消息響應
線程間同步的方式有四種:MFC提供的同步對象
1 臨界區 CCriticalSection
2 事件 CEvent
3 互斥量 CMutex
4 信号量 CSemaphore
1 使用場合:當多個線程 通路一個獨占性的共享資源
使用方法:(1)定義CCriticalSection 的一個全局對象。 CCriticalSection ;
(2)在需要保護的代碼或資源前調用。
critical_section.Lock();
線程調用這個函數Lock()獲得臨界區對象。如果其他線程沒有占有這個臨界區對象,調用Lock()的線程獲得臨界區對象;否則
調用Lock()的線程就被挂起,放入一個由系統維護的隊列,直到占有臨界區的線程結束為止。
(3)通路臨界區完閉,
critical_section.Unlock();
再通俗一點講,就是線程A執行到critical_section.Lock();語句時,如果其它線程(B)正在執行critical_section.Lock();語句 後且critical_section. Unlock();語句前的語句時,線程A就會等待,直到線程B執行完critical_section. Unlock();語句 ,線程A才會繼續執行。
2 使用場合:CEvent 支援事件。當事件是一個線程在某種情況下用來喚醒另外一個線程的同步對象。
狀态:有信号和無信号
分類:自動事件和人工事件。自動和人工的差別是:CEvent 的無信号狀态是由系統自動重置的還是有開發者調用函數實作的。
1、CEvent(BOOL bInitiallyOwn=FALSE,
BOOL bManualReset=FALSE,
LPCTSTR lpszName=NULL,
LPSECURITY_ATTRIBUTES lpsaAttribute=NULL);
bInitiallyOwn:指定事件對象初始化狀态,TRUE為有信号,FALSE為無信号;
bManualReset:指定要建立的事件是屬于人工事件還是自動事件。TRUE為人工事件,FALSE為自動事件;
後兩個參數一般設為NULL,在此不作過多說明。
2、BOOL CEvent::SetEvent();
将 CEvent 類對象的狀态設定為有信号狀态。如果事件是人工事件,則 CEvent 類對象保持為有信号狀态,直到調用成員函數ResetEvent()将 其重新設為無信号狀态時為止。如果CEvent 類對象為自動事件,則在SetEvent()将事件設定為有信号狀态後,CEvent 類對象由系統自動重置為無信号狀态。
如果該函數執行成功,則傳回非零值,否則傳回零。 3、BOOL CEvent::ResetEvent();
該函數将事件的狀态設定為無信号狀态,并保持該狀态直至SetEvent()被調用時為止。由于自動事件是由系統自動重置,故自動事件不需
要調用該函數。如果該函數執行成功,傳回非零值,否則傳回零。
使用方法:線程(A),線程(B) 如果想先執行線程(A)在執行線程(B),那麼線上程(A)中代碼的最後調用 CEvent對象的SetEvent(),将事件對象置為有信号狀态,線上程(B)代碼的開始調用WaitForSingleObject() 那麼WaitForSingleObject()函數就可以一直監視CEvent對象一旦此對象為有信号狀态那麼線程(B)就可以執行了,進而實作了現場同步。
3 互斥對象和臨界區很像。CMutex
差別:CMutex既可以在程序間使用,也可以在同一程序的各個線程間使用。
4 CSemaphore
使用場合:允許多個線程同時通路一個共享資源,同時規定了同時通路這個共享資源的線程數目。
其内部有一個計數器當有線程通路這個共享資源時 計數器自動減1 當計數器為0時就不運作其他線程在通路共享資源。
(1)建立一個信号量對象
CSemaphore semaphore(2,2);
定義一個CSingleLock,CMutiLock;
CSingleLock singlelock(semaphore);
要減小這個信号Semaphore的計數值,隻須調用CSingleLock對象的成員函數Lock()即可:
SingleLock.Lock();
同樣,通過調用UnLock()來釋放這個信号量,即:SingleLock.UnLock();
示例代碼:http://www.vckbase.com/document/viewdoc/?id=762