您的位置:首页 > 移动开发 > Objective-C

线程同步 等待函数 WaitForSingleObject WaitForMultipleObjects

2015-11-09 16:23 561 查看

0、思考



1、相关api

WaitForSingleObject
WaitForMultipleObjects
WaitForInputIdle(对父进程比较有用)
MsgWaitForMultipleObjects
MsgWaitForMultipleObjectsEx
WaitForDebugEvent
SignalObjectAndWait


2、写在前面

等待函数:是一个线程自愿进入等待状态,直到指定的内核对象被触发为止。(内核对象:Event,Mutex,Semaphore,Process,Thread,
Waitable timer,Job,Change notification,Console input,Memory resource notification)
等待成功所引起的副作用:对象的状态发生了变化。(举个栗子:假设线程等待一个自动重置事件对象,当事件对象被触发时,函数返回WAIT_OBJECT_0
之前事件变为非触发状态)


3、api说明

// hHandle:要等待的内核对象
// dwMilliseconds:指定线程最多愿意花多长时间来等待对象被触发;(通常:INFINITE)
// WAIT_OBJECT_0:线程等待对象被触发;WAIT_TIMEOUT:等待超时;WAIT_FAILED:(具体原因通过GetLastError知道)
WINBASEAPI
DWORD
WINAPI
WaitForSingleObject(
__in HANDLE hHandle,
__in DWORD dwMilliseconds
);

// 允许调用线程同时等待多个内核对象的触发状态
// nCount:希望函数检查的内核对象的数量
// lpHandles:内核对象句柄的数组
// bWaitAll:指定内核对象中的一个被触发为止(false);直到指定内核对象中的全部被触发为止(true)
// dwMilliseconds:同WaitForSingleObject
// WAIT_OBJECT_0:如果bWaitAll为ture,则表示所有对象都被触发;如果bWaitAll为false,返回[WAIT_OBJECT_0, WAIT_OBJECT_0 + nCount - 1]
分别对应lpHandles数组中的某个内核对象
WINBASEAPI
DWORD
WINAPI
WaitForMultipleObjects(
__in DWORD nCount,
__in_ecount(nCount) CONST HANDLE *lpHandles,
__in BOOL bWaitAll,
__in DWORD dwMilliseconds
);

// 等待进程创建并初始化完毕(父进程能够知道子进程已经初始化完毕的唯一方法就是等待子进程直到它不再处理任何输入为止;WM_KEY消息创建窗口耗时也可用此)
// hProcess:进程句柄。
// dwMilliseconds:等待时间。
WINUSERAPI
DWORD
WINAPI
WaitForInputIdle(
__in HANDLE hProcess,
__in DWORD dwMilliseconds
);

// 与WaitForMultipleObjects类似,不同之处于,不仅内核对象被触发的时候调用线程变成可调度状态,而且当窗口消息需要被派送到一个由调用线程创建的窗口是,它们也会变成可调度。创建窗口的线程和执行与用户界面相关的任务的线程不应该使用WaitForMultipleObjects,因为会妨碍线程对用户在界面上的操作响应。
// dwWakeMask:QS_INPUT | QS_POSTMESSAGE | QS_TIMER | QS_PAINT | QS_HOTKEY | QS_SENDMESSAGE。(通常为QS_ALLINPUT)
WINUSERAPI
DWORD
WINAPI
MsgWaitForMultipleObjects(
__in DWORD nCount,
__in_ecount_opt(nCount) CONST HANDLE *pHandles,
__in BOOL fWaitAll,
__in DWORD dwMilliseconds,
__in DWORD dwWakeMask
);

// dwFlags:等待类型,0、MWMO_ALERTABLE、MWMO_INPUTAVAILABLE、MWMO_WAITALL(通常为0)
WINUSERAPI
DWORD
WINAPI
MsgWaitForMultipleObjectsEx(
__in DWORD nCount,
__in_ecount_opt(nCount) CONST HANDLE *pHandles,
__in DWORD dwMilliseconds,
__in DWORD dwWakeMask,
__in DWORD dwFlags
);

// windows内建的绝佳调试支持
WINBASEAPI
BOOL
WINAPI
WaitForDebugEvent(
__in LPDEBUG_EVENT lpDebugEvent,
__in DWORD dwMilliseconds
);

// 通过一个原子操作来触发一个内核对象并等待另一个内核对象
// hObjectToSignal:必须是事件、信号量或互斥量
// hObjectToWaitOn:必须是进程、线程、作业、控制台输入、变更通知、事件、计时器、信号量、互斥量
// dwMilliseconds:等待时间
// bAlertable:线程处于等待状态时,是否应该能够对添加到队列中的异步过程调用进行处理
WINBASEAPI
DWORD
WINAPI
SignalObjectAndWait(
__in HANDLE hObjectToSignal,
__in HANDLE hObjectToWaitOn,
__in DWORD dwMilliseconds,
__in BOOL bAlertable
);


4、C++封装

无(ps:可通过其他文章查看使用)


5、顺藤摸瓜

如果多个线程等待同一个内核对象,那么当对象被触发时,系统如何决定唤醒哪个线程?
算法机制:先入先出,通常情况下等待时间最长的线程得到对象;但是,系统内部的一些操作可能会改变这种行为。(举个栗子:调试进程使得线程频繁
挂起和恢复)
SignalObjectAndWait:特别受欢迎,原因一:触发一个对象并等待另一个对象,让一个函数完成两个操作可以节省处理时间;原因二:触发和等待操作是通过原子方式执行。


鸣谢

内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: