一.前言
執行緒是執行路徑。乙個程序至少要有乙個執行緒,也可能包含多個執行緒。若程序關閉了,則在程序中所有的執行緒也自動被銷毀。當我們在乙個應用程式中建立乙個執行緒時,實際上,它是第二個執行緒。在c或c++中,程式的入口函式是main或wmain(unicode版本)。在windows的運用程式中,程式的入口點是winmain或wwinmain。當程式啟動時,作業系統建立第乙個執行緒。因此,windows是乙個多工作業系統。
二.執行緒函式
執行緒函式跟普通函式一樣,它帶有乙個long void的指標引數。我們可以傳任何型別的資料給這個void型別的指標資料。乙個簡單的執行緒函式如下:
1.
threadfunction(
lpvoid
param)
2.
三.執行緒屬性
執行緒的優先順序控制程序中線程的優先順序。執行緒屬性如下:
● 最高:thread_priority_highest
● 高於標準:thread_priority_above_normal
● 標準:thread_priority_normal
● 低於標準:thread_priority_below_normal
● 空閒:thread_priority_idel
我們可以用createthread函式設定執行緒優先順序。在win32 api函式中,我們用getthreadpriority 和 setthreadpriority獲取和設定執行緒優先順序;或者我們也可以用cwinthread的函式,在**中,我們可以自由的呼叫它。優先順序函式返回乙個bool型別的變數。
四.各個平台下的多執行緒
1.c執行時庫的多執行緒
● _beginthread
● _beginthreadex
● _endthread
● _endthreadex
以上c執行時庫的函式都包含在標頭檔案process.h中。要確保在microsoft visual studio的工程設定是multithreaded dll。在c執行時庫中,通常是用_beginthread和_beginthreadex函式來建立執行緒。但是,這些執行緒有些不同。_beginthreadex有一些附加的引數,比如安全性和執行緒位址。我們用_beginthread來建立執行緒的話,要用_endthread來結束執行緒。_endthread將自動關閉執行緒的控制代碼。但是,若我們用_endthreadex的話,要用win32 api的函式closehandle來關閉執行緒控制代碼。c執行時庫包含了執行緒本地儲存區(tls)。我們可以用api或特定的編譯**去使用執行緒本地儲存區。tlsalloc,tlsfree,tlsgetvalue和tlssetvalue通常用來儲存指定的執行緒資料。microsoft建議,假如你用了c執行時庫的_beginthread函式,你就不要使用像exitthread或者createthread這樣的win32 api函式。因為,假如你那樣使用的話,可能會導致死鎖。_beginthread在建立執行緒的時候使用多個引數。我們的例子是基於乙個簡單控制台的程式。使用者鍵入執行緒數目建立執行緒,然後我們執行每乙個執行緒。
01.
// secound thread function
02.
void
threadproc(
void
*param);
03.
// first thread
04.
int
main()
05.
22.
return
0;
23.
}
24.
25.
26.
void
threadproc(
void
*param)
27.
主線程用win32 api的函式waitforsingleobject來等待另乙個執行緒的完成。
2.mfc的多執行緒
cwinthread是所有執行緒操作的基類。mfc支援兩種型別的執行緒:使用者介面執行緒和工作執行緒。使用者介面執行緒是基於windows訊息。工作程序執行在後台程序中。cwinthread支援工作執行緒和使用者介面執行緒。但是,這裡只討論工作執行緒。
mfc的類層次結構
cobject
ccmdtarget
cwinthread
資料成員:
● m_hthread – 當前執行緒控制代碼
● m_bautodelete – 設定執行緒是否自動釋放
● m_nthreadid – 當前執行緒的id
函式成員:
● createthread – 啟動執行緒的exec執行
● suspendthread – 掛起執行緒, 增加執行緒掛起數。
● resumethread – 恢復執行緒,減少執行緒堆疊數。
● setthreadpriority – 設定執行緒的優先順序(low,below low or high)。
● getthreadpriority – 獲取執行緒的優先順序。
在mfc中,並不是所有的成員函式都是類成員。我們也可以訪問一些全域性函式。這些函式都以afx開頭。在mfc的執行緒中,afxbeginthread和afxendthread是運用的最廣泛的函式。我們用afxbeginthread函式建立執行緒。afxbeginthread語法如下:
1.
cwinthread* afxbeginthread( afx_threadproc threadproc,
lpvoid
param,
2.
int
npriority = thread_priority_normal,
uint
nstacksize = 0,
3.
dword
dwcreateflags = 0, lpsecurity_attributes lpsecurityattrs = null );
threadproc是afxbeginthread函式的第乙個引數,我們在這個引數中使用執行緒函式的名稱,在這個引數中傳入void型別的引數指標,此函式的返回值型別是uint。afxbeginthread的其它引數是可選的。預設的優先順序是thread_priority_normal。當想要改變其優先順序時,可以呼叫函式setthreadpriority。我們同樣也可以獲得優先順序。
afxendthread用來終止執行緒,afxendthread有乙個退出**引數列表。
01.
cwinthread *pthread = afxbeginthread( threadfunction, &data);
02.
03.
uint
threadfunction(
lpvoid
param)
04.
3.win32的多執行緒
win32的執行緒使用createthread函式來建立,createthread函式的語法如下:
1.
handle
createthread( lpsecurity_attributes lpthreadattributes,
2.
dword
dwstacksize, lpthread_start_routine lpstartaddress,
3.
lpvoid
lpparameter,
dword
dwcreationflags,
lpdword
lpthreadid);
當我們想終止執行緒的時候有下面幾種方法:
(1)使用terminatethread函式
(2)使用exitthread函式
(3)使用return
但是advanced windows建議我們使用return方法。terminatethread或exitthread不能正確的清除執行緒堆疊。函式getthreadtimes通常用來獲取執行緒的執行時間。函式getcurrentthreadid是獲取當前執行緒的id。sleep指定執行緒休眠,單位為毫秒。比如,sleep(1000)將使執行緒休眠1000毫秒。函式swithtothread的功能是切換到其他執行緒。suspendthread用來掛起乙個執行緒。waitforsingleobject等待乙個指定的執行緒,直到執行緒完全完成它的工作。函式waitformultipleobject用來等待多個事件。等待的情形:更改通知、控制台輸入、事件、工作、互斥、程序、訊號量、執行緒和可等待定時器。
五.執行緒的優點
多執行緒運用程式使用100%的cpu效率。當我們建立乙個程序,要需要更多的記憶體空間。多執行緒運用程式跟程序共享乙個記憶體空間。每乙個執行緒都包含了棧,因此,執行緒比程序占有的記憶體更少。乙個程序可能或可能沒包含多個執行緒,假如你在程序中開啟了多個執行緒,所有的執行緒都共用這個程序的位址空間。
多執行緒在C Win32和MFC下的使用方法
一 前言 執行緒是執行路徑。乙個程序至少要有乙個執行緒,也可能包含多個執行緒。若程序關閉了,則在程序中所有的執行緒也自動被銷毀。當我們在乙個應用程式中建立乙個執行緒時,實際上,它是第二個執行緒。在c或c 中,程式的入口函式是main或wmain unicode版本 在windows的運用程式中,程式...
多執行緒在C Win32和MFC下的使用方法
一 前言 執行緒是執行路徑。乙個程序至少要有乙個執行緒,也可能包含多個執行緒。若程序關閉了,則在程序中所有的執行緒也自動被銷毀。當我們在乙個應用程式中建立乙個執行緒時,實際上,它是第二個執行緒。在c或c 中,程式的入口函式是main或wmain unicode版本 在windows的運用程式中,程式...
VC(Win32 MFC)多執行緒程式設計
在日常的 vc 開發中,執行緒是我們經常使用的。但是我們在使用過程中並沒有考慮過會不會有什麼問題,我們配置的引數是否正確,到底應該如何配置執行緒函式的各個引數,才能使機器發揮最大的效能。所以根據作者多年的使用執行緒的經驗,做本次分享,讓眾多的工程師的門更能詳細的了解 vc 執行緒的使用,能夠更加正確...