轉自:http://www.chenhangyu.com/?p=175
建立線程的函數有很多種, 包括CreateThread、_beginthread、 _beginthreadex和AfxBeginThread. 用法在MSDN上都有詳述, 這裡做個筆記摘錄.
1, CreateThread是不安全的,很多參考書上,都說不要用CreateThread 建立線程、並用CloseHandle來關閉這個線程,因為一些技術性的問題,會導致記憶體流失. 直接在CreateThread API建立的線程中使用sprintf,malloc,strcat等涉及CRT儲存堆操作的CRT庫函數是不安全的.
2, _beginthread和_beginthreadex在CreateThread上做了改進,可以安全的進行操作但是,必須線上程結束的時候相應的調用_endthread或_endthreadex.
3, beginthreadex比_beginthread更安全一些,beginthread隱式調用了CloseHandle關閉了線程控制代碼,而與_beginthreadex成對使用的_endthreadex則沒有關閉線程的控制代碼,需要顯示調用CloseHandle來關閉線程控制代碼,從邏輯上更安全.
4, 在MFC程式中,使用AfxBeginThread.
5, 在非MFC程式中,盡量使用_beginthreadex.
使用_beginthreadex啟動線程和傳遞參數的例子:
#include "windows.h"
#include "stdio.h"
#include "process.h"
typedef struct
{
int seqno;
}PARA_T;
HANDLE hHendle;
DWORD threadProc(LPVOID pParameter); //線程調用的函數
void main(int argc, char* argv[])
{
int i;
// 跑5個線程
for (i=0; i<5; ++i)
{
PARA_T aPara;
aPara.seqno = i;
_beginthreadex(NULL, 0, (void *)&threadProc, (void *)&aPara, 0, hHendle);
Sleep(500);
}
getchar();
}
DWORD threadProc(LPVOID pParameter)
{
iPara = (PARA_T *)pParameter;
printf("-----%d\n",iPara->seqno);
return 0;
}
結果是:
—–0
—–1
—–2
—–3
—–4
一些需要注意的地方:
1,線程依賴於主進程,主進程退出了,線程也都退出.所以例子這裡是getchar在等待,同樣,可以使用一個狀態位+while迴圈來判斷線程是否處理完畢.在這個例子裡,要是把Sleep(500); 和 getchar()都去掉, 運行一下,就會明白這個意思了.
2,CloseThread函數並不是把線程哢嚓了,而是把線程控制代碼哢嚓了. 線程執行完就會return,就當做一個函數執行完一樣退出.在這裡close的意思是, 主進程放棄對線程的控制了.
3,關於參數的傳遞,使用結構體方式更好一些, 新定義或者new一個結構體, 也避免了使用直接變數做為參數的時候被外部條件改變值.