zoukankan      html  css  js  c++  java
  • Windows编程-- 等待函数


    两个等待函数 一个单线程,一个多线程

    等待函数可使线程自愿进入等待状态,直到一个特定的内核对象变为已通知状态为止。(FangSH注:如果内核对象没有变为通知即线程永远等待下去。)这些等待函数中最常用的是WaitForSingleObject :

    DWORD WaitForSingleObject(HANDLEhObject,
    DWORD dwMilliseconds);

    第一个参数hObject标识一个能够支持被通知/未通知的内核对象(前面列出的任何一种对象都适用)。(FangSH注:句柄)

    第二个参数dwMilliseconds指明等待对象变为已通知状态所需的等待时间。(时间间隔以毫秒为单位,INFINITE表示直到等到hHandle为已通知状态)。传递INFINITE有些危险。如果对象永远不变为已通知状态,那么调用线程永远不会被唤醒,它将永远处于死锁状态,不过,它不会浪费宝贵的CPU时间。

    下面是如何用一个超时值而不是INFINITE来调用WaitForSingleObject的例子:

    DWORD dw = WaitForSingleObject(hProcess,5000);
    switch(dw)
    {
    case WAIT_OBJECT_0:
    // The process terminated.
    break;

    case WAIT_TIMEOUT:
    // The process did not terminate within 5000 milliseconds.
    break;

    case WAIT_FAILED:
    // Bad call to function (invalid handle?)
    break;
    }

    上面这个代码告诉系统,在特定的进程终止运行之前,或者在5000ms时间结束之前,调用线程不应该变为可调度状态。因此,如果进程终止运行,那么这个函数调用将在不到5000ms的时间内返回,如果进程尚未终止运行,那么它在大约5000ms时间内返回。注意,不要为d wMillisecond传递0。如果传递了0,WaitForSingleObject函数将总是立即返回。

    WaitForSingleObject的返回值能够指明调用线程为什么再次变为可调度状态

    如果线程等待的对象变为已通知状态,那么返回值是WAIT_OBJECT_0

    如果设置的超时已经到期,则返回值是WA I T_ TIMEOUT

    如果将一个错误的值(如一个无效句柄)传递给Wa itForSingleObject,那么返回值将是WA IT_FAILED(若要了解详细信息,可调用GetLastError)。

    WaitForMultipleObjects调用线程同时查看若干个内核对象的已通知状态

    DWORD WaitForMultipleObjects(DWORDdwCount,
    CONST HANDLE
    * phObjects,
    BOOL fWaitAll,
    DWORD dwMilliseconds);

    dwCount参数用于指明想要让函数查看的内核对象的数量这个值必须在1与MAXIMUM _WA I T_OBJECTS(在Windows头文件中定义为64)之间。

    phObjects参数是指向内核对象句柄的数组的指针

    可以以两种不同的方式来使用WaitForMultipleObjects函数

    一种方式是让线程进入等待状态,直到指定内核对象中的任何一个变为已通知状态

    另一种方式是让线程进入等待状态,直到所有指定的内核对象都变为已通知状态

    fWaitAll参数告诉该函数,你想要让它使用何种方式。如果为该参数传递TRUE,那么在所有对象变为已通知状态之前,该函数将不允许调用线程运行

    dwMilliseconds参数的作用与它在WaitForSingleObject中的作用完全相同。如果在等待的时候规定的时间到了,那么该函数无论如何都会返回。同样,通常为该参数传递INFINITE,但是在编写代码时应该小心,以避免出现死锁情况。

    WaitForSingleObject函数的返回值告诉调用线程,为什么它会被重新调度。

    可能的返回值是WA IT_FAILEDWAIT_TIMEOUT,这两个值的作用是很清楚的。

    如果为fWaitAll参数传TRUE同时所有对象均变为已通知状态,那么返回值是WAIT_OBJECT_0

    如果为fWaitAll传递FA LSE,那么一旦任何一个对象变为已通知状态,该函数便返回

    在这种情况下,你可能想要知道哪个对象变为已通知状态。返回值是WAIT_OBJECT_0与(WA IT_OBJECT_0 + dwCount - 1)之间的一个值。

    换句话说,如果返回值不是WA IT_TIMEOUT,也不是WAIT_FA ILED,那么应该从返回值中减去WAIT_OBJECT_0。产生的数字是作为第二个参数传递给WaitForMultipleObjects的句柄数组中的索引。该索引说明哪个对象变为已通知状态。下面是说明这一情况的一些示例代码:

    HANDLE h[3];
    h[
    0] = hProcess1;
    h[
    1] = hProcess2;
    h[
    2] = hProcess3;
    DWORD dw
    = WaitForMultipleObjects(3,h, FALSE, 5000);
    switch(dw)
    {
    case WAIT_FAILED:
    // Bad call to function (invalid handle?)
    break;

    case WAIT_TIMEOUT:
    // None of the objects became signaled within 5000 milliseconds.
    break;

    case WAIT_OBJECT_0 + 0:
    // The process identified by h[0] (hProcess1) terminated.
    break;

    case WAIT_OBJECT_0 + 1:
    // The process identified by h[1] (hProcess2) terminated.
    break;

    case WAIT_OBJECT_0 + 2:
    // The process identified by h[2] (hProcess3) terminated.
    break;
    }

    如果为fWaitAll参数传递FA LSE,WaitForSingleObjects就从索引0开始向上对句柄数组进行扫描,同时已通知的第一个对象终止等待状态。这可能产生一些你不希望有的结果。例如,通过将3个进程句柄传递给该函数,你的线程就会等待3个子进程终止运行。如果数组中索引为0的进程终止运行,WaitForSingleObject就会返回。这时该线程就可以做它需要的任何事情,然后循环反复,等待另一个进程终止运行。如果该线程传递相同的3个句柄,该函数立即再次返回WAIT_OBJECT_0。除非删除已经收到通知的句柄,否则代码就无法正确地运行。

    FangSH   2010-12-29

  • 相关阅读:
    采用FPGA实现音频模数转换器
    serial-input, parallel-output (SIPO) chip : TPIC6595 , 74HC164 , 74HC4094 or 74HC595
    DLL Injection and Hooking
    实战DELPHI:远程线程插入(DLL注入)
    将DLL挂接到远程进程之中(远程注入)
    [转]远程注入DLL : 取得句柄的令牌 OpenProcessToken()
    向其他进程注入代码的三种方法
    将dll文件注入到其他进程中的一种新方法
    busdog is a filter driver for MS Windows (XP and above) to sniff USB traffic.
    The Eclipse runtime options
  • 原文地址:https://www.cnblogs.com/fangshenghui/p/1926489.html
Copyright © 2011-2022 走看看