Windows API 多線程-學習筆記(一)
一, winindows 下多線程的建立與撤銷:
windows 下多線程建立函數有兩種,一種是調用系統API: CreateThread(), 另一種是調用C運作時函數庫_beginthread()或_beginthreadex(),建立線程如果不再使用
//函數原型:
//The thread object remains in the system until the thread has terminated and all handles to it have been closed through a call to CloseHandle.
//建立線程如果不再使用傳回的線程句柄,應用CloseHandle關閉,
HANDLE WINAPI CreateThread(
__in LPSECURITY_ATTRIBUTES lpThreadAttributes, //安全類型, NULL時為預設安全類型
//可以用SetThreadPriority或GetThreadPriority設定或獲得
__in SIZE_T dwStackSize, //線程棧大小 NULL時為預設大小,好像是 1M
__in LPTHREAD_START_ROUTINE lpStartAddress, //線程函數位址
__in LPVOID lpParameter, //線程函數的參數,在些傳給線程
__in DWORD dwCreationFlags, //線程建立标志 如果是CREATE_SUSPENDED
//則線程建立時是暫停的,要用ResumeThread
//喚醒線程,如果是NULL則立即進入排程隊列
//STACK_SIZE_PARAM_IS_A_RESERVATION與線程棧有關
__out LPDWORD lpThreadId //傳入一個DWORD變量位址,獲得線程ID,也可傳NULL, 可以用GetThreadId獲得線程ID
);
//結束一個線程, 可以自然的結束.
VOID WINAPI ExitThread(
__in DWORD dwExitCode
);
//線程函數模型, ThreadProc可以換成其它自定義的名稱
DWORD WINAPI ThreadProc(
[in] LPVOID lpParameter
);
//簡單版 (最好不要用,)
uintptr_t _beginthread(
void( *start_address )( void * ), //線程函數位址
unsigned stack_size, //線程棧大小,
void *arglist //線程函數參數
);
// 與C Runtime Library 一起用時沒問題(好像是使用了TLS,使原來的全局變量在每個線程中都有,)
uintptr_t _beginthreadex( //與CreateThread一樣.
void *security, //安全類型
unsigned stack_size, //線程棧大小
unsigned ( *start_address )( void * ), //線程函數位址
void *arglist, //線程函數參數
unsigned initflag, //線程标志
unsigned *thrdaddr //線程ID
);
//線上程函數中調用,結束調用的線程, 可以自然的結束.
void _endthread( void );
void _endthreadex(
unsigned retval //線程結束代碼.
);
//例程(vc2008)
HANDLE h_thread;
DWORD ThreadProc(char* str)
{
for (int i = 0; i != 10; i++)
{
printf("No. %d: %s\n", i, str);
//std::cout << "NO." << i << ": " << str << std::endl;
}
Sleep(5000);
return 0;
}
void TestThread()
{
DWORD thread_id;
h_thread = CreateThread(
NULL,
NULL,
(LPTHREAD_START_ROUTINE)ThreadProc,
(LPVOID)"Test string passed to ThreadProc",
NULL,
&thread_id);
for (int i = 0; i != 10; i++)
{
printf("No. %d: In the main thread.\n", i);
}
WaitForMultipleObjects(
1,
&h_thread,
true,
INFINITE);
CloseHandle(h_thread);
}