CreateThread函數,createthread
當使用CreateProcess調用時,系統將建立一個進程和一個主線程。CreateThread將在主線程的基礎上建立一個新線程,大致做如下步驟:
1在核心對象中分配一個線程標識/控制代碼,可供管理,由CreateThread返回
2把線程退出碼置為STILL_ACTIVE,把線程掛起計數置1
3分配context結構
4分配兩頁的實體儲存體以準備棧,保護頁設定為PAGE_READWRITE,第2頁設為PAGE_GUARD
5lpStartAddr和lpvThread值被放在棧頂,使它們成為傳送給StartOfThread的參數
6把context結構的棧指標指向棧頂(第5步)指令指標指向startOfThread函數
文法:
hThread = CreateThread(&security_attributes, dwStackSize, ThreadProc,pParam, dwFlags, &idThread) ;
HANDLE CreateThread(
LPSECURITY_ATTRIBUTES lpThreadAttributes, // pointer to security attributes
DWORD dwStackSize, // initial thread stack size
LPTHREAD_START_ROUTINE lpStartAddress, // pointer to thread function
LPVOID lpParameter, // argument for new thread
DWORD dwCreationFlags, // creation flags
LPDWORD lpThreadId // pointer to receive thread ID
);
第一個參數是指向SECURITY_ATTRIBUTES型態的結構的指標。在Windows 98中忽略該參數。在Windows NT中,它被設為NULL。
第二個參數是用於新線程的初始堆棧大小,預設值為0。在任何情況下,Windows根據需要動態延長堆棧的大小。
第三個參數是指向線程函數的指標。函數名稱沒有限制,但是必須以下列形式聲明:
DWORD WINAPI ThreadProc (PVOID pParam) ;
第四個參數為傳遞給ThreadProc的參數。這樣主線程和從屬線程就可以共用資料。
第五個參數通常為0,但當建立的線程不馬上執行時為旗標CREATE_SUSPENDED。線程將暫停直到呼叫ResumeThread來恢複線程的執行為止。
第六個參數是一個指標,指向接受執行緒ID值的變數。
注意:臨界區要線上程執行前初始化,因為線程一但被建立即開始運行(除非手工掛起),但線程建立後在初始化臨界區可能出現問題
如:孫鑫MFC中的現象
int main()
{
InitializeCriticalSection(&g_cs); //先初始化臨界區
HANDLE handle1=CreateThread(NULL,0,ThreadProc1,NULL,0,NULL);
HANDLE handle2=CreateThread(NULL,0,ThreadProc2,NULL,0,NULL);
CloseHandle(handle1);
CloseHandle(handle2);
Sleep(4000);
DeleteCriticalSection(&g_cs);
return 0;
}
CreateThread()函數每個參數都是什,線程問題幫我都解釋一下好
HANDLE CreateThread(
LPSECURITY_ATTRIBUTES lpsa,
DWORD cbStack,
LPTHREAD_START_ROUTINE lpStartAddr,
LPVOID lpvThreadParam,
DWORD fdwCreate,
LPDWORD lpIDThread
);
lpsa:線程控制代碼的安全屬性,比如子進程是否可以繼承這個線程控制代碼,一般情況設定為NULL
cbStack:線程棧大小,一般取0表示預設大小
lpStartAddr:線程入口函數 typedef DWORD (__stdcall *LPTHREAD_START_ROUTINE) (
void* lpThreadParameter );在win32程式中預設的調用函數約定就是WINAPI ,__stdcall = WINAPI 。因此你可以聲明你的入口函數為:
DWORD WINAPI ThreadProc( void* lpParamete) {//線程中你要做的事情}
lpvThreadParam:就是線程入口函數的參數,就是ThreadProc( void* lpParamete) 的參數
fdwCreate:控制線程建立的標誌一般為0,表示線程立即啟動。如果你想建立之後把線程掛起來可以傳入CREATE_SUSPENDED ,傳入這個參數你需要再適當的地方調用ResumeThread 啟動線程
lpIDThread:是線程ID傳回值,這個用來接收線程返回的ID
寫了這麼多我還是怕你不懂:
我舉個例子吧,我不保證能運行成功,我也沒去編譯
DWORD WINAPI ThreadProc( void* lpParameter)
{
int *x = (int*)lpParameter;//獲得參數的地址
MessageBox(NULL,TEXT("adf"),NULL,MB_OK);
}
DWORD dwThreadID;
int x = 0;
HANDLE hThread = CreateThread(0,0,ThreadProc,(void*)&x,0,&dwThreadID);
CloseHandle(hThread);
想學習好windows編程MSDN是必須瞭解的,你居然不知道什麼是MSDN,MSDN就是協助文檔,你可以到百度搜一下並把它下載過來,這對你MFC、Windows API、C/C++等很有協助的
(C++多線程問題)CreateThread()函數問題
(1)LPTHREAD_START_ROUTINE lpStartAddress 指定了線程函數的起始地址,建立線程將從此地址開始執行,直到return語句返回,把控制權交給作業系統。
(2)LPVOID lpParameter 則是傳遞給線程函數的參數,也即傳遞給(1)中指定的線程函數的地址。
以下是一個例子:建立線程後,將轉到線程函數執行,遇到return語句後返回到main函數。
#include <iostream>
#include <windows.h>
using namespace std;
/*ThreadProc為LPTHREAD_START_ROUTINE lpStartAddress
*參數指定的線程函數.lpParam則是LPVOID lpParameter指
*定的傳遞給線程函數的參數*/
DWORD WINAPI ThreadProc(LPVOID lpParam)
{
for (int i = 0;i < 20;++i)
{
cout << "I am from a thread,count = " << i <<endl;
}
return 0;
}
int main()
{
HANDLE hThread;
DWORD dwThreadID;
hThread = ::CreateThread(
NULL,
NULL,
ThreadProc,// 線程入口地址
NULL,
0,
&dwThreadID);
::WaitForSingleObject(hThread,INFINITE);
::CloseHandle(hThread);
return 0;
}