1,等待函数WaitrForSingleObject(HANDLE , WaitTime),当等待的对象被触发时候返回值:
DWORD WINAPI WaitForSingleObject(
_In_ HANDLE hHandle,
_In_ DWORD dwMilliseconds
);
WAIT_OBJECT_0:表示对象被触发
WAIT_TIMEOUT:表示等待超时
WAIT_FAILED: 表示出错,比如传入了无效句柄
2,WaitForMultipleObjects可以同时检查多个内核对象的触发状态:
DWORD WINAPI WaitForMultipleObjects(
_In_ DWORD nCount,
_In_ const HANDLE *lpHandles,
_In_ BOOL bWaitAll,
_In_ DWORD dwMilliseconds
);
nCount表示要检查的内核对象的数量
lpHandles表示检查的内核对象数组
bWaitAll表示是等待lpHandles中的nCount个对象全部变为触发状态返回还是只要一个变为触发状态就返回。
如果bWaitAll传入FALSE,那么返回值是WAIT_OBJECT_0 到 WAIT_OBJECT_0 + dwCount - 1之间的任意一个值。
如果在Wait的过程中一个已经触发的内核对象再次变为未触发状态,那么就还会继续等待这个对象触发才会返回。
自动重置事件对象:在WaitForXXX时,函数返回时候会将自动重置事件对象由触发状态变为未触发状态。
手动重置事件对象与自动重置事件对象区别是:自动重置事件触发时候只有一个等待事件的线程变为可调度,而手动重置对象触发时候所有等待的线程都会变为可调度。
3,创建事件内核对象:CreateEvent
HANDLE WINAPI CreateEvent(
_In_opt_ LPSECURITY_ATTRIBUTES lpEventAttributes,
_In_ BOOL bManualReset,
_In_ BOOL bInitialState,
_In_opt_ LPCTSTR lpName
);
第二个bManualReset为TRUE表示创建手动重置事件,为FALSE表示创建自动重置事件。
第三个bInitialState为TRUE表示事件初始化为触发状态。
第四个指定一个名字,其他进程可以通过OpenEvent或CreateEvent传入名字来打开同一个进程内核对象。
SetEvent : 设置事件为触发状态。
ResetEvent:设置事件为未触发状态。
4,CreateWaitableTimer:
HANDLE WINAPI CreateWaitableTimer(
_In_opt_ LPSECURITY_ATTRIBUTES lpTimerAttributes,
_In_ BOOL bManualReset,
_In_opt_ LPCTSTR lpTimerName
);
创建一个可等待的计时器内核对象,创建后处于未触发状态。
用SetWaitTimer可以让计时器处于触发状态。
BOOL WINAPI SetWaitableTimer(
_In_ HANDLE hTimer,
_In_ const LARGE_INTEGER *pDueTime,
_In_ LONG lPeriod,
_In_opt_ PTIMERAPCROUTINE pfnCompletionRoutine,
_In_opt_ LPVOID lpArgToCompletionRoutine,
_In_ BOOL fResume
);
pDueTime表示计时器第一次触发的时间(本地时间绝对时间20xx-xx-xx),为负数表示相对时间,是100ns的整数倍,如果传入1秒就应该传入-10000000。
lPeriod表示的是计时器触发的间隔时间,如果为0表示触发一次后不再触发。
pfnCompletionRoutine表示设置的APC回调函数
CancleWaitableTimer表示取消指定的计时器。
5,APC调用
当SetWaitableTimer的调用线程处于可提醒状态时候(调用SleepEx , WaitForSingleObjectEx , WaitForMultipleObjectEx , MsgWaitForMultipleObjectsEx , SignalObjectAndWait)进入的等待状态,系统就会将函数的pfnCompletionRoutine添加进APC队列。
6,信号量:CreateSemaphoreEx
HANDLE WINAPI CreateSemaphoreEx(
_In_opt_ LPSECURITY_ATTRIBUTES lpSemaphoreAttributes,
_In_ LONG lInitialCount,
_In_ LONG lMaximumCount,
_In_opt_ LPCTSTR lpName,
_Reserved_ DWORD dwFlags,
_In_ DWORD dwDesiredAccess
);
使用计数:内核对象的使用计数
最大资源计数:最大的资源数量
当前资源计数:表示信号量当前可用资源的数量
ReleaseSemphore来增加当前信号量的资源计数
7,互斥量Mutex
CreateMutex , CreateMutexEx , OpenMutex
HANDLE WINAPI CreateMutex(
_In_opt_ LPSECURITY_ATTRIBUTES lpMutexAttributes,
_In_ BOOL bInitialOwner,
_In_opt_ LPCTSTR lpName
);
bInitialOwner为FALSE表示将互斥量的ID和递归计数设置为0,这表示处于触发状态,设置为TRUE表示将ID设置为调用线程的线程ID,并且递归计数设置为1,表示未触发状态。
使用计数:内核对象使用计数
线程ID:与互斥量所绑定的线程ID,如果处于触发状态则ID为0
递归计数:一个线程占用互斥量的次数
ReleaseMutex来释放互斥量
8,SignalObjectAndWait
DWORD WINAPI SignalObjectAndWait(
_In_ HANDLE hObjectToSignal,
_In_ HANDLE hObjectToWaitOn,
_In_ DWORD dwMilliseconds,
_In_ BOOL bAlertable
);
用于触发一个对象然后等待另一个对象,在内部会执行与ReleaseMutext,ReleaseSemaphore,SetEvent等价的操作。