Windows下多线程相关函数

Windows下多线程相关函数

1)创建线程 CreateThread

WINBASEAPI
_Ret_maybenull_
HANDLE
WINAPI
CreateThread(
    _In_opt_ LPSECURITY_ATTRIBUTES lpThreadAttributes,
    _In_ SIZE_T dwStackSize,
    _In_ LPTHREAD_START_ROUTINE lpStartAddress,
    _In_opt_ __drv_aliasesMem LPVOID lpParameter,
    _In_ DWORD dwCreationFlags,
    _Out_opt_ LPDWORD lpThreadId
    );
// 参数介绍
// lpThreadAttributes:线程内核对象的安全属性,一般传入NULL表示使用默认设置;
// dwStackSize:线程栈空间大小。传入0表示使用默认大小(1MB);
// lpStartAddress:新线程所执行的线程函数地址,多个线程可以使用同一个函数地址;
// lpParameter:传给线程函数的参数;
// dwCreationFlags:指定额外的标志来控制线程的创建,为0表示线程创建之后立即就可以进行调度,如果为CREATE_SUSPENDED表示线程创建后暂停运行,此时无法调度,直到调用Resume Thread();
// lpThreadId:返回线程的ID号,传入NULL表示不需要返回线程ID号。
// 返回值
// 成功:返回新线程的句柄;失败:返回NULL。

2)等待函数——使线程进入等待状态,直到指定的内核对象被触发 WaitForSingleObject

WINBASEAPI
DWORD
WINAPI
WaitForSingleObject(
    _In_ HANDLE hHandle,
    _In_ DWORD dwMilliseconds
    );
// 参数介绍
// hHandle:要等待的内核对象;
// dwMilliseconds:最长等待时间,以毫秒为单位,传入1000表示1秒,传入0表示立即返回,传入INFINITE表示无限等待。
// 由于线程的句柄在线程运行时是未触发的,线程结束运行,句柄处于触发状态。故可以用其来等待一个线程结束运行。
// 返回值
// 在指定的时间内对象被触发,函数返回WAIT_OBJECT_0。超过最长等待时间对象扔未被触发,返回WAIT_TIMEOUT,传入参数有错误,将返回WAIT_FAILED。

3)多线程中对变量的原子性操作 Interlock

// 递增操作
LONG
__cdecl
InterlockedIncrement (
    _Inout_ LONG volatile *lpAddend
    );
// 递减操作
LONG
__cdecl
InterlockedDecrement (
    _Inout_ LONG volatile *lpAddend
    );
// 赋值操做
LONG
__cdecl
InterlockedExchange (
    _Inout_ LONG volatile *Target,
    _In_    LONG Value
    );
// 返回变量执行增减操作之后的值
LONG
__cdecl
InterlockedExchangeAdd (
    _Inout_ LONG volatile *Addend,
    _In_    LONG Value
    );

4)关键段 CriticalSection

// 初始化关键段
WINBASEAPI
VOID
WINAPI
InitializeCriticalSection(
    _Out_ LPCRITICAL_SECTION lpCriticalSection
    );
// 进入关键段
WINBASEAPI
VOID
WINAPI
EnterCriticalSection(
    _Inout_ LPCRITICAL_SECTION lpCriticalSection
    );
// 离开关键段
WINBASEAPI
VOID
WINAPI
LeaveCriticalSection(
    _Inout_ LPCRITICAL_SECTION lpCriticalSection
    );
// 销毁关键段
WINBASEAPI
VOID
WINAPI
DeleteCriticalSection(
    _Inout_ LPCRITICAL_SECTION lpCriticalSection
    );

// 微软为提高关键段性能,将旋转锁合并到关键段中,此时进入关键段会利用一个旋转锁不断循环,尝试一段时间后才会将线程切换到等待状态。具体使用下面两个函数:
// 初始化关键段并设置旋转次数(旋转次数一般设为4000)
WINBASEAPI
_Must_inspect_result_
BOOL
WINAPI
InitializeCriticalSectionAndSpinCount(
    _Out_ LPCRITICAL_SECTION lpCriticalSection,
    _In_ DWORD dwSpinCount
    );
// 修改关键段的旋转次数
WINBASEAPI
DWORD
WINAPI
SetCriticalSectionSpinCount(
    _Inout_ LPCRITICAL_SECTION lpCriticalSection,
    _In_ DWORD dwSpinCount
    );

5)事件 Event

// 创建事件
WINBASEAPI
_Ret_maybenull_
HANDLE
WINAPI
CreateEvent(
    _In_opt_ LPSECURITY_ATTRIBUTES lpEventAttributes,
    _In_ BOOL bManualReset,
    _In_ BOOL bInitialState,
    _In_opt_ LPCSTR lpName
    );
// 参数介绍:
// lpEventAttributes:安全控制,一般直接传入NULL;
// bManualReset:确定事件是手动置位还是自动置位,传入TRUE表示手动置位,传入FALSE表示自动置位。如果自动置位,则对改时间调用WaitForSingleObject()后会自动调用ResetEvent()使时间编程未触发状态;
// bInitialState:事件的初始状态,传入TRUE表示已触发;
// lpName:事件名称,传入NULL表示匿名事件。

// 依据名称获取一个事件句柄
WINBASEAPI
_Ret_maybenull_
HANDLE
WINAPI
OpenEvent(
    _In_ DWORD dwDesiredAccess,
    _In_ BOOL bInheritHandle,
    _In_ LPCSTR lpName
    );
// 参数介绍:
// dwDesiredAccess:访问权限,对事件一般传入EVENT_ALL_ACCESS;
// bInheritHandle:时间句柄继承性,一般传入TRUE;
// lpName:不同进程中的各线程可以通过名称来确保他们访问同一个事件。

// 触发事件
WINBASEAPI
BOOL
WINAPI
SetEvent(
    _In_ HANDLE hEvent
    );
// 每次触发后,必须有一个或多个处于等待状态下的线程变成可调度状态。

// 将事件设为未触发
WINBASEAPI
BOOL
WINAPI
ResetEvent(
    _In_ HANDLE hEvent
    );

// 将事件触发后立即将事件设置为未触发,相当于触发一个时间脉冲
WINBASEAPI
BOOL
WINAPI
PulseEvent(
    _In_ HANDLE hEvent
    );
// 此函数相当于SetEvent()后立即调用ResetEvent();

注意:事件的清理和销毁只需要调用CloseHandle()就可以完成清理与销毁。

6)互斥量 Mutex

// 创建互斥量
WINBASEAPI
_Ret_maybenull_
HANDLE
WINAPI
CreateMutexA(
    _In_opt_ LPSECURITY_ATTRIBUTES lpMutexAttributes,
    _In_ BOOL bInitialOwner,
    _In_opt_ LPCSTR 
    );
// 参数说明:
// lpMutexAttributes:安全控制,一般直接传入NULL;
// bInitialOwner:确定互斥量的初始拥有者。如果传入TRUE表示互斥量对象内部会记录创建它的线程的线程ID号,并将递归计数设置为1,由于该线程ID非0,故互斥量处于未触发状态,如果传入FALSE,那么互斥量对象内部的线程ID号将设置为NULL,递归计数设置为0,意味互斥量不为任何线程占有,处于触发状态。
// lpName:设置互斥量的名称,在多个进程中的线程就是通过名称来确保它们访问的是同一个互斥量。
// 返回值
// 成功:返回一个表示互斥量的句柄;失败:返回NULL。

// 打开互斥量
WINBASEAPI
_Ret_maybenull_
HANDLE
WINAPI
OpenMutex(
    _In_ DWORD dwDesiredAccess,
    _In_ BOOL bInheritHandle,
    _In_ LPCWSTR lpName
    );

// 参数说明:
// dwDesiredAccess:访问权限,对互斥量一般传入MUTEX_ALL_ACCESS;
// bInheritHandle:互斥量句柄继承性,一般传入TRUE即可;
// lpName:表示名称,某一个进程中的线程创建互斥量后,其它进程中的线程可以通过这个函数来找到这个互斥量
// 返回值:
// 成功:返回一个表示互斥量的句柄;失败:返回NULL。

// 触发互斥量
WINBASEAPI
BOOL
WINAPI
ReleaseMutex(
    _In_ HANDLE hMutex
    );
// 访问互斥资源前应该要调用等待函数,访问结束时就要调用ReleaseMutex()来表示自己已经结束访问,其他线程可以开始访问了。

// 注意:由于互斥量是内核对象,故使用CloseHandle()就可以清理互斥量。

7)信号量 Semaphore

// 创建信号量
WINBASEAPI
_Ret_maybenull_
HANDLE
WINAPI
CreateSemaphore(
    _In_opt_ LPSECURITY_ATTRIBUTES lpSemaphoreAttributes,
    _In_     LONG lInitialCount,
    _In_     LONG lMaximumCount,
    _In_opt_ LPCSTR lpName
    );
// 参数说明:
// lpSemaphoreAttributes:安全控制
// lInitialCount:初始资源数量
// lMaximumCount:最大并发数量
// lpName:信号量的名称,传入NULL表示匿名信号量

// 打开信号量
WINBASEAPI
_Ret_maybenull_
HANDLE
WINAPI
OpenSemaphore(
    _In_ DWORD dwDesiredAccess,
    _In_ BOOL bInheritHandle,
    _In_ LPCSTR lpName
    );
// 参数说明
// dwDesiredAccess:访问权限,对一般传入SEMAPHORE_ALL_ACCESS;
// bInheritHandle:信号量句柄继承性,一般传入TRUE;
// lpName:名称,不同进程中的各线程可以通过名称来确保它们访问同一个信号量。

// 递增信号量的当前资源计数
WINBASEAPI
BOOL
WINAPI
ReleaseSemaphore(
    _In_ HANDLE hSemaphore,
    _In_ LONG lReleaseCount,
    _Out_opt_ LPLONG lpPreviousCount
    );
// 参数说明:
// hSemaphore:信号量的句柄;
// lReleaseCount:增加的个数,必须大于0且不超过最大资源数量;
// lpPreviousCount:用来传出先前的资源计数,设为NULL表示不需要传出。

// 注意:由于信号量是内核对象,故使用CloseHandle()就可以完成信号量的清理和销毁。

8)读写锁 SRWLock

// 初始化读写锁
WINBASEAPI
VOID
WINAPI
InitializeSRWLock(
    _Out_ PSRWLOCK SRWLock
    );
// 写入者线程申请写资源
WINBASEAPI
_Acquires_exclusive_lock_(*SRWLock)
VOID
WINAPI
AcquireSRWLockExclusive(
    _Inout_ PSRWLOCK SRWLock
    );
// 写入者写资源完毕,释放对资源的占用
WINBASEAPI
_Releases_exclusive_lock_(*SRWLock)
VOID
WINAPI
ReleaseSRWLockExclusive(
    _Inout_ PSRWLOCK SRWLock
    );
// 读取者线程申请读资源
WINBASEAPI
_Acquires_shared_lock_(*SRWLock)
VOID
WINAPI
AcquireSRWLockShared(
    _Inout_ PSRWLOCK SRWLock
    );
// 读取者线程结束读取资源,释放资源的占用
WINBASEAPI
_Releases_shared_lock_(*SRWLock)
VOID
WINAPI
ReleaseSRWLockShared(
    _Inout_ PSRWLOCK SRWLock
    );

参考文献:http://blog.csdn.net/morewindows/article/details/7392749

你可能感兴趣的:(多线程)