|
VC多線程編程學(xué)習(xí)筆記(一)
最近兩天在學(xué)多線程編程,有了一些心得,寫下來和大家一起共勉。文中一些部分引用了韓耀旭的文章《多線程編程》http://www./document/viewdoc/?id=1704和MSDN資料。 一、緣起 工作上要用到串口編程,本來一直是用mscomm控件來進(jìn)行串口通訊的,后來覺得這個(gè)控件功能不靈活,想直接使用api編程,那就不可避免的要使用多線程技術(shù):用一個(gè)支線程一直掛在那里監(jiān)聽串口,就不影響主線程的消息循環(huán)了。
二、為何要用多線程 有時(shí)候需要把程序的運(yùn)行掛起一段時(shí)間,我們會(huì)用到 Sleep(5000); 來讓程序掛起5秒鐘,而這個(gè)時(shí)候,程序在這5秒鐘里就“死”在那里了,不再響應(yīng)其他任何消息。 或者有時(shí)候會(huì)用一個(gè) While(1) 這樣一個(gè)死循環(huán)去完成一些監(jiān)聽工作,但這樣的話,主界面也會(huì)“死”在那里。 這些也許都不是程序員的本意,那我們可以使用多線程技術(shù),把一些耗時(shí)的操作放到支線程里去,而不影響主線程的消息循環(huán)。
三、相關(guān)函數(shù) 1. HANDLE CreateThread(LPSECURITY_ATTRIBUTES lpThreadAttributes,DWORD dwStackSize,LPTHREAD_START_ROUTINE lpStartAddress,LPVOID lpParameter,DWORD dwCreationFlags,LPDWORD lpThreadID ); 該函數(shù)在其調(diào)用進(jìn)程的進(jìn)程空間里創(chuàng)建一個(gè)新的線程,并返回已建線程的句柄,其中各參數(shù)說明如下:
如果創(chuàng)建成功則返回線程的句柄,否則返回NULL。 2. DWORD SuspendThread(HANDLE hThread); 該函數(shù)用于掛起指定的線程,如果函數(shù)執(zhí)行成功,則線程的執(zhí)行被終止。 3. DWORD ResumeThread(HANDLE hThread); 該函數(shù)用于結(jié)束線程的掛起狀態(tài),執(zhí)行線程。 4. VOID ExitThread(DWORD dwExitCode); 該函數(shù)用于線程終結(jié)自身的執(zhí)行,主要在線程的執(zhí)行函數(shù)中被調(diào)用。其中參數(shù)dwExitCode用來設(shè)置線程的退出碼。 5. BOOL TerminateThread(HANDLE hThread,DWORD dwExitCode); 一般情況下,線程運(yùn)行結(jié)束之后,線程函數(shù)正常返回,但是應(yīng)用程序可以調(diào)用TerminateThread強(qiáng)行終止某一線程的執(zhí)行。各參數(shù)含義如下:
使用TerminateThread()終止某個(gè)線程的執(zhí)行是不安全的,可能會(huì)引起系統(tǒng)不穩(wěn)定;雖然該函數(shù)立即終止線程的執(zhí)行,但并不釋放線程所占用的資源。因此,一般不建議使用該函數(shù)。 6. BOOL PostThreadMessage(DWORD idThread,UINT Msg,WPARAM wParam,LPARAM lParam); 該函數(shù)將一條消息放入到指定線程的消息隊(duì)列中,并且不等到消息被該線程處理時(shí)便返回。
調(diào)用該函數(shù)時(shí),如果即將接收消息的線程沒有創(chuàng)建消息循環(huán),則該函數(shù)執(zhí)行失敗。 7. DWORD WaitForSingleObject(HANDLE hHandle,DWORD dwMilliseconds);
四、兩個(gè)重要元素 1. Volatile 2. 死鎖
五、一個(gè)簡(jiǎn)單的使用多線程技術(shù)的小對(duì)話框(使用mfc) 在vc中新建一個(gè)對(duì)話框程序,布局如圖:
1.在對(duì)話框的.cpp文件中加入以下兩句: #include "afxmt.h" //為了使用事件對(duì)象CEvent ,所需的頭文件
2.加入兩個(gè)全局函數(shù)作為兩個(gè)支線程的入口函數(shù): UINT proc1(LPARAM lParam)
UINT proc2(LPARAM lParam)
3.為兩個(gè)只讀的文本框添加控件變量 m_edit1 ,m_edit2 4.為按鈕添加單擊事件函數(shù): void CExampleMultiThreadDlg::OnStart() 0, (LPTHREAD_START_ROUTINE)proc1, &m_edit1, 0, NULL); 0, (LPTHREAD_START_ROUTINE)proc2, &m_edit2, 0, NULL); 5.運(yùn)行后,點(diǎn)擊開始按鈕,兩個(gè)分線程便開始工作了,線程1會(huì)每秒鐘刷新一次第一個(gè)對(duì)話框,每刷新5次,線程2就在第二個(gè)對(duì)話框中刷新一下當(dāng)前時(shí)間。 程序中用到的CEvent對(duì)象是個(gè)線程同步對(duì)象,用來在線程之間發(fā)送信息,我會(huì)在下面的學(xué)習(xí)筆記中闡述用法。
|
|
|