http://blog.csdn.net/gpengtao/article/details/7767090
2012
DWORD = unsigned long
HANDLE = void *
LPVOID = void *
WINAPI = __stdcall
//線程函數(shù)的原型
DWORD WINAPI ThreadFunc(LPVOID);
//創(chuàng)建線程:
HANDLE CreateThread(
LPSECURITY_ATTRIBUTES lpThreadAttributes,
//安全屬性,一般為NULL
SIZE_T dwStackSize,
//棧大小,0表示缺省大小1M
LPTHREAD_START_ROUTINE lpStartAddress,
//函數(shù)指針
LPVOID lpParameter,
//函數(shù)的參數(shù)
DWORD dwCreationFlags,
//線程標(biāo)志,0表示立即激活
LPDWORD lpThreadId
//保存線程的id號
);
#include <process.h>
uintptr_t __cdecl _beginthreadex(void * _Sequrity,
unsigned int _StackSize,
unsigned int (__stdcall *_StartAddress)(void*),
void * _ArgList,
unsigned int _InitFlag,
unsigned int * _ThrdAddr);
//C運行庫創(chuàng)建線程函數(shù)
//關(guān)閉核心對象
BOOL CloseHandle(HANDLE hObject);//除非對內(nèi)核對象的所有引用都已關(guān)閉,否則該對象不會實際刪除
線程對象的默認(rèn)引用計數(shù)是2。
當(dāng)你調(diào)用CloseHandle( )時,引用計數(shù)下降1,當(dāng)線程結(jié)束時,引用計數(shù)再降1。
只有當(dāng)兩件事情都發(fā)生了(不管順序如何)的時候,這個對象才會被真正清除。
//核心對象包括:
進程(processes)
線程(threads)
文件(files)
事件(events)
信號量(semaphores)
互斥器(mutexes)
管道(Pipes:分為named 和anonymous 兩種)
//獲取線程退出代碼
BOOL GetExitCodeThread(HANDLE hThread, LPVOID IpExitCode);
如果線程還未結(jié)束,IpExitCode存儲的是 STILL_ACTIVE,函數(shù)返回的仍然是true。
//結(jié)束線程
1. void ExitThread(DWORD dwExitCode);
該函數(shù)將終止線程的運行,并導(dǎo)致操作系統(tǒng)清除該線程使用的所有操作系統(tǒng)資源。但是,C++資源(如C++類對象)將不被撤消。
所以最好從線程函數(shù)返回,而不是通過調(diào)用ExitThread來返回。
2. BOOL TerminateThread(HANDLE hThread, DWORD dwExitCode);//結(jié)束指定的線程,這個最好不用
3. #include <process.h>
void _endthread(void);
void _endthreadex(void);
_endthread 自動關(guān)閉線程句柄。因此,當(dāng)使用 _beginthread 和 _endthread時,不要通過調(diào)用 Win32 API CloseHandle 顯式關(guān)閉線程句柄。
_endthreadex 不關(guān)閉線程句柄。 因此,當(dāng)使用 _beginthreadex 和 _endthreadex時,必須通過調(diào)用 Win32 API CloseHandle 關(guān)閉線程處理。
這兩個函數(shù)同樣不調(diào)用對象的析構(gòu)函數(shù)。
//獲得錯誤編號
DWORD GetLastError(void);
//等待一個對象
DWORD WaitForSingleObject(HANDLE hHandle, DWORD dwMiliseconds);
等待指定對象若干毫秒。0毫秒表示立刻返回,INFINITE(-1)表示阻塞。
返回值:
WAIT_OBJECT_0 :0 核心對象已被激活
WAIT_ABANDONED :128 當(dāng)hHandle為mutex時,如果擁有mutex的線程在結(jié)束時沒有釋放核心對象會引發(fā)此返回值
WAIT_ABANDONED_0:WAIT_ABANDONED
WAIT_TIMEOUT :258 等待超時
WAIT_FAILED :-1 出現(xiàn)錯誤,可通過GetLastError得到錯誤代碼
//當(dāng)線程正在執(zhí)行時,線程對象處于未激發(fā)狀態(tài)。當(dāng)線程結(jié)束時,線程對象就被激發(fā)了。
//等待多個(核心)對象
DOWORD WaitForMultipleObjects(DWORD nCount, const HANDLE *lpHandles,
BOOL bWaitAll, DWORD dwMiliseconds);
bWaitAll為ture時,等待數(shù)組中所有的對象被激發(fā);false時返回被激發(fā)對象在數(shù)組中的下標(biāo)。
//臨界區(qū)
CRITICAL_SECTION critical_sec;
//定義一個臨界區(qū),名字為critical_sec
void InitializeCriticalSection(LPCRITICAL_SECTION IpCriticalSection);//初始化臨界區(qū)
void DeleteCriticalSection(LPCRITICAL_SECTION IpCriticalSection);
//刪除臨界區(qū)
void EnterCriticalSection(LPCRITICAL_SECTION IpCriticalSection);
//進入臨界區(qū)
void LeaveCriticalSection(LPCRITICAL_SECTION IpCriticalSection);
//離開臨界區(qū)
//互斥器
HANDLE CreateMutex(LPSECURITY_ATTRIBUTES IpMutexAttibutes,//安全屬性
BOOL bInitialOwner,
//初始化后是否屬于初始化線程
LPCWSTR IpName);
//mutex的名字
WaitSingleObject();
//獲得互斥器
BOOL ReleaseMutex(HANDLE hMutex);//釋放互斥器
如果一個線程結(jié)束時沒有釋放互斥器,下一個等待中的線程的等待會以WAIT_ABANDONED_0返回。
CloseHandle();
//刪除互斥器
//信號量
HANDLE CreateSemaphore(LPSECURITY_ATTRIBUTES lpSemAttributes,//安全屬性
LONG lInitialCount,
//信號量初始值
LONG lMaximumCount,
//信號量的最大值
LPCWSTR lpName);
//名字
WaitForSingleObject();
//獲得一個信號量
BOOL ReleaseSemphore(HANDLE hSem, LONG IReleaseCount,LPLONG IpPreviousCount);
//釋放信號量,第二個參數(shù)說明釋放幾個,第三個參數(shù)接收存儲釋放前信號量的值的地址
CloseHandle();//刪除信號量
//事件
HANDLE CreateEvent(LPSECURITY_ATTRIBUTES lpEveAttr,//安全屬性
BOOL bManualReset,
//是否手動設(shè)置為非激活
BOOL bInitialState,
//初始狀態(tài),激活或者非激活
LPCWSTR lpName);
//名字
BOOL SetEvent(HANDLE hEvent);//設(shè)置事件為激活狀態(tài)
BOOL PulseEvent(HANDLE hEvent);//設(shè)置事件為激活狀態(tài)
說明:SetEvent()和PulseEvent()沒有區(qū)別;
當(dāng)事件設(shè)置為“手動非激活”時,這兩個函數(shù)激活事件喚醒所有的阻塞;
當(dāng)事件設(shè)置為“自動非激活”時,事件的激活喚醒一個阻塞。
//我理解為手動Reset比較慢,其他線程還有機會被喚醒,而自動的是系統(tǒng)干的,很速度地Reset了,所以其他線程也就沒有機會了。
WaitForSingleObject();
//等待事件
BOOL ResetEvent(HANDLE hEvent);//設(shè)置事件為非激活狀態(tài)
CloseHandle();
//刪除事件
//原子操作函數(shù)
LONG InterlockedIncrement(LPLONG IpTarget);//加1,并返回加1后的值
LONG InterlockedDecrement(LPLONG IpTarget);//減1,并返回減1后的值
LONG InterlockedExchange(LPLONG IpTarget, LONG IValue);//設(shè)定新的值,返回舊的值
//運行線程,掛起線程
DWORD ResumeThread(HANDLE hThread);
//讓掛起的進程繼續(xù)運行(如創(chuàng)建線程時設(shè)置倒數(shù)第二個參數(shù)使線程創(chuàng)建后立刻掛起,調(diào)用該函數(shù)再讓它運行)
DWORD SuspendThread(HANDLE hThread);//掛起進程