CreateThread
生活随笔
收集整理的這篇文章主要介紹了
CreateThread
小編覺得挺不錯的,現在分享給大家,幫大家做個參考.
CreateThread是一種微軟在Windows API中提供了建立新的線程的函數,該函數在主線程的基礎上創建一個新線程。線程中止運行后,線程對象仍然在系統中,必須通過CloseHandle函數來關閉該線程對象。
在很多參考書上,都說不要用CreateThread 創建線程、并用CloseHandle來關閉這個線程,因為這樣做會導致內存泄漏,而應該用_beginthread來創建線程,_endthread來銷毀線程。 中文名目錄
CreateThread步驟
編輯 CreateThread將在主線程的基礎上創建一個新線程,大致做如下步驟: 1.在內核對象中分配一個線程標識/句柄,可供管理,由CreateThread返回 2.把線程退出碼置為STILL_ACTIVE,把線程掛起計數置1 3.分配context結構 4.分配兩頁的物理存儲以準備棧,保護頁設置為PAGE_READWRITE,第2頁設為PAGE_GUARD 5.lpStartAddr和lpvThread值被放在棧頂,使它們成為傳送給StartOfThread的參數 6.把context結構的棧指針指向棧頂(第5步)指令指針指向startOfThread函數CreateThread函數原型
編輯 MSDN中CreateThread原型: HANDLE CreateThread( LPSECURITY_ATTRIBUTES lpThreadAttributes,//SD SIZE_T dwStackSize,//initialstacksize LPTHREAD_START_ROUTINE lpStartAddress,//threadfunction LPVOID lpParameter,//threadargument DWORD dwCreationFlags,//creationoption LPDWORD lpThreadId//threadidentifier ) processthreadsapi.h中CreateThread原型: WINBASEAPI _Ret_maybenull_ HANDLE WINAPI CreateThread( _In_opt_LPSECURITY_ATTRIBUTES lpThreadAttributes, _In_SIZE_T dwStackSize, _In_LPTHREAD_START_ROUTINE lpStartAddress, _In_opt___drv_aliasesMemLPVOID lpParameter, _In_DWORD dwCreationFlags, _Out_opt_LPDWORD lpThreadId );CreateThread參數說明
編輯 lpThreadAttributes:指向SECURITY_ATTRIBUTES型態的結構的指針。在Windows 98中忽略該參數。在Windows NT中,NULL使用默認安全性,不可以被子線程繼承,否則需要定義一個結構體將它的bInheritHandle成員初始化為TRUE dwStackSize,設置初始棧的大小,以字節為單位,如果為0,那么默認將使用與調用該函數的線程相同的棧空間大小。任何情況下,Windows根據需要動態延長堆棧的大小。 lpStartAddress,指向線程函數的指針,形式:@函數名,函數名稱沒有限制,但是必須以下列形式聲明: DWORD WINAPI 函數名 (LPVOID lpParam) ,格式不正確將無法調用成功。 //也可以直接調用void類型 //但lpStartAddress要這樣通過LPTHREAD_START_ROUTINE轉換如: (LPTHREAD_START_ROUTINE)MyVoid //然后在線程聲明為: void MyVoid() { return; } lpParameter:向線程函數傳遞的參數,是一個指向結構的指針,不需傳遞參數時,為NULL。 dwCreationFlags :線程標志,可取值如下 (1)CREATE_SUSPENDED(0x00000004):創建一個掛起的線程, (2)0:表示創建后立即激活。 (3)STACK_SIZE_PARAM_IS_A_RESERVATION(0x00010000):dwStackSize參數指定初始的保留堆棧 的大小,否則,dwStackSize指定提交的大小。該標記值在Windows 2000/NT and Windows Me/98/95上不支持。 lpThreadId:保存新線程的id。 返回值:函數成功,返回線程句柄;函數失敗返回false。若不想返回線程ID,設置值為NULL。 函數說明: 創建一個線程。 語法: hThread = CreateThread (&security_attributes, dwStackSize, ThreadProc,pParam, dwFlags, &idThread) ; 一般并不推薦使用 CreateThread函數,而推薦使用RTL庫里的System單元中定義的 BeginThread函數,因為這除了能創建一個線程和一個入口函數以外,還增加了幾項保護措施。 在MFC程序中,應該調用AfxBeginThread函數,在Visual C++程序中應調用_beginthreadex函數。CreateThread內存泄漏
編輯 其實,真正的原因并非如此。看如下一段代碼: ?| 1 2 3 4 5 6 7 8 | HANDLECreateThread( LPSECURITY_ATTRIBUTESlpThreadAttributes,//線程安全屬性 DWORDdwStackSize,//堆棧大小 LPTHREAD_START_ROUTINElpStartAddress,//線程函數 LPVOIDlpParameter,//線程參數 DWORDdwCreationFlags,//線程創建屬性 LPDWORDlpThreadId//線程ID ); |
CreateThread示例
編輯 CreateThread 函數從一個進程里面創建一個線程。這個開始的線程必須指定開始執行代碼的地址,新線程執行。有代表性的,開始地址就是一個函數名。這個函數有一個參數,并且返回一個 DWORD 值。一個進程里面同時有多個線程在執行。 下面這個例子演示如何創建一個新線程,執行本地定義的函數。 ThreadProc. 建立的線程動態分配內存傳遞信息到每個線程的實例中。線程函數負責釋放這些內存。 被調用的線程用 WaitForMultipleObjects 持續等待,直到所有的工作線程退出。在線程退出后,關掉線程函數的句柄。 ?| 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 | #include?<windows.h> #include?<strsafe.h>//win2003SDK必須安裝 要不無此頭文件。此文件是為了實現StringCchPrintf,StringCchLength。 #define?MAX_THREADS????3 #define?BUF_SIZE????255 typedef?struct?_MyData{ int?val1; int?val2; }MYDATA,*PMYDATA; DWORD?WINAPI?ThreadProc(LPVOID?lpParam) { ????HANDLE?hStdout; ????PMYDATA?pData; ????TCHAR?msgBuf[BUF_SIZE]; ????size_tcchStringSize; ????DWORD?dwChars; ????hStdout=GetStdHandle(STD_OUTPUT_HANDLE); ????if(hStdout==INVALID_HANDLE_VALUE) ????return?1; ????//Cast?the?parameter?to?the?correct?data?type. ????pData=(PMYDATA)lpParam; ????//Print?the?parameter?values?using?thread-safe?functions. ????StringCchPrintf(msgBuf,BUF_SIZE,TEXT("Parameters=%d,%d\n"), ????pData->val1,pData->val2); ????StringCchLength(msgBuf,BUF_SIZE,&cchStringSize); ????WriteConsole(hStdout,msgBuf,cchStringSize,&dwChars,NULL); ????//Free?the?memory?allocated?by?the?caller?for?the?thread ????//data?structure. ????HeapFree(GetProcessHeap(),0,pData); ????return?0; } void?main() { ????PMYDATA?pData; ????DWORD?dwThreadId[MAX_THREADS]; ????HANDLE?hThread[MAX_THREADS]; ????int?i; ????//Create?MAX_THREADS?worker?threads. ????for(i?=?0;?i?<?MAX_THREADS;?i++) ????{ ????????//Allocate?memory?for?thread?data. ????????pData=(PMYDATA)HeapAlloc(GetProcessHeap(),HEAP_ZERO_MEMORY, ????????sizeof(MYDATA)); ????????if(pData==NULL) ????????ExitProcess(2); ????????//Generate?unique?data?for?each?thread. ????????pData->val1=i; ????????pData->val2=i+100; ????????hThread[i]=CreateThread( ????????NULL,//default?security?attributes ????????0,//use?default?stack?size ????????ThreadProc,//thread?function ????????pData,//argument?to?thread?function ????????0,//use?default?creation?flags ????????&dwThreadId[i]);//returns?the?thread?identifier ????????//Check?there?turn?value?for?success. ????????if(hThread[i]==NULL) ????????{ ????????????ExitProcess(i); ????????} ????} ????//Wait?until?all?threads?have?terminated. ????WaitForMultipleObjects(MAX_THREADS,hThread,TRUE,INFINITE); ????//Close?all?thread?handle?supon?completion. ????for(i=0;i<MAX_THREADS;i++) ????{ ????????CloseHandle(hThread[i]); ????}???? } |
總結
以上是生活随笔為你收集整理的CreateThread的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: CreateEvent的用法
- 下一篇: 计算机知识探索怎么写,计算机基础知识及探