• <ins id="pjuwb"></ins>
    <blockquote id="pjuwb"><pre id="pjuwb"></pre></blockquote>
    <noscript id="pjuwb"></noscript>
          <sup id="pjuwb"><pre id="pjuwb"></pre></sup>
            <dd id="pjuwb"></dd>
            <abbr id="pjuwb"></abbr>

            牽著老婆滿街逛

            嚴(yán)以律己,寬以待人. 三思而后行.
            GMail/GTalk: yanglinbo#google.com;
            MSN/Email: tx7do#yahoo.com.cn;
            QQ: 3 0 3 3 9 6 9 2 0 .

            通過(guò)異步程序調(diào)用(APC)實(shí)現(xiàn)的定時(shí)功能

            轉(zhuǎn)載自:http://www.vckbase.com/document/viewdoc/?id=1587

            編譯:張海粟

              定時(shí)器是一個(gè)在特定時(shí)間或者規(guī)則間隔被激發(fā)的內(nèi)核對(duì)象。結(jié)合定時(shí)器的異步程序調(diào)用可以允許回調(diào)函數(shù)在任何定時(shí)器被激發(fā)的時(shí)候執(zhí)行。本文的例子代碼顯示了如何實(shí)現(xiàn)。
              使用本定時(shí)器時(shí),你需要把常量_WIN32_WINNT定義為0x0400,并且此常量應(yīng)該在包之前定義,以確保聲明合適的定時(shí)器原型函數(shù)。
              通過(guò)調(diào)用CreateWaitableTimer()可以創(chuàng)建一個(gè)定時(shí)器,此函數(shù)返回一個(gè)指向內(nèi)核對(duì)象的句柄。若定時(shí)器已經(jīng)存在,你可以通過(guò)使用OpenWaitableTimer()獲得一個(gè)進(jìn)程相關(guān)的句柄。無(wú)論是通過(guò)CreateWaitableTimer() 還是通過(guò)OpenWaitableTimer()獲得的句柄,在不需要定 時(shí)器時(shí)必須釋放,方法是使用函數(shù)CloseHandle()。
              定時(shí)的時(shí)間通過(guò)調(diào)用SetWaitableTimer()來(lái)設(shè)置,可以設(shè)置為一個(gè)特定的時(shí)刻(如December 16, 1999 at 9:45 PM)或者一個(gè)相對(duì)的時(shí)間(如從現(xiàn)在起每五分鐘)。函數(shù)SetWaitableTime()定時(shí)的時(shí)間參數(shù)要求LARGE_INTEGER類型。這個(gè)值應(yīng)該符合在結(jié)構(gòu)體FILETIME中描述的格式。如果值是正的,代表一個(gè)特定的時(shí)刻。如果值是負(fù)的,代表以100納秒為單位的相對(duì)時(shí)間。后面的示例代碼中使用的是相對(duì)時(shí)間。在調(diào)用SetWaitableTimer()函數(shù)后,定時(shí)器將在每5秒被激發(fā)一次。
              你也可以將定時(shí)器設(shè)置為周期性的自我激發(fā),方法是向SetWaitableTimer()的第三個(gè)參數(shù)傳遞一個(gè)周期參數(shù)(以毫秒為單位)。在CreateWaitableTimer()的第二個(gè)參數(shù)傳遞FALSE可以產(chǎn)生一個(gè)自動(dòng)歸零的定時(shí)器。本例設(shè)置周期為兩秒的定時(shí)器。
              當(dāng)設(shè)置了定時(shí)器之后,你就可以將APC與其結(jié)合起來(lái)。這里把APC函數(shù)稱作完全例程。完全例程的地址作為SetWaitableTimer()的第四個(gè)參數(shù)。第五個(gè)參數(shù)是一個(gè)空類型的指針,你可以使用它來(lái)傳遞完全例程的參數(shù)。
              在所有的APC中,要執(zhí)行一個(gè)完全例程則線程必須處于監(jiān)聽狀態(tài)。完全例程將總是被調(diào)用SetWaitableTimer()的相同的線程執(zhí)行,所以此線程必須將必須其自身置于監(jiān)聽狀態(tài)。可以調(diào)用下面的任何一個(gè)監(jiān)聽函數(shù)來(lái)完成監(jiān)聽狀態(tài)的設(shè)置:

            • SleepEx();
            • WaitForSingleObjectEx();
            • WaitForMultipleObjectsEx();
            • MsgWaitForMultipleObjectsEx();
            • SignalObjectAndWait();

              任何一個(gè)線程都有一個(gè)APC隊(duì)列。在調(diào)用上面的任何一個(gè)函數(shù)時(shí),如果線程的APC隊(duì)列中有實(shí)體,則此線程不會(huì)進(jìn)入休眠狀態(tài),取而代之要做的是將實(shí)體從APC隊(duì)列中取出,然后調(diào)用相應(yīng)的完全例程。
              如果在APC隊(duì)列中不存在實(shí)體,那么線程將會(huì)被掛起,直至等待條件滿足為止。滿足等待條件的有:一個(gè)實(shí)體加入到APC隊(duì)列中,超時(shí),激活句柄等,以及在調(diào)用MsgWaitForMultipleObjectsEx()情況下,一個(gè)消息進(jìn)入到線程的一個(gè)消息隊(duì)列中。若等待條件滿足的是APC隊(duì)列中的一個(gè)實(shí)體,那么線程會(huì)被激活,并且執(zhí)行完全例程,這種情況下的函數(shù)的返回值是 WAIT_IO_COMPLETION.

            【重要提示】

            1、在執(zhí)行完一個(gè)完全例程之后,系統(tǒng)會(huì)檢查在APC中剩下的實(shí)體以處理。一個(gè)監(jiān)視函數(shù)僅僅在處理完所有APC實(shí)體后才返回。因此,如果實(shí)體加入到APC隊(duì)列的速度比處理的更快的話,則調(diào)用這些函數(shù)可能永遠(yuǎn)也不能返回。特別當(dāng)定時(shí)等待的時(shí)間比起要求執(zhí)行完全例程的時(shí)間更短的話,這種情況更容易發(fā)生。 
            2、當(dāng)使用APC來(lái)實(shí)現(xiàn)定時(shí)器時(shí),設(shè)置定時(shí)的線程不應(yīng)該等待定時(shí)器的句柄。如果等待定時(shí)器的句柄的話,則喚起這個(gè)線程的原因是定時(shí)器被激活,而不是有實(shí)體加入到APC隊(duì)列中。這時(shí)線程將不再處于監(jiān)聽狀態(tài),所以完全例程也不會(huì)被調(diào)用。在本例中,Sleep()被用于將線程置于監(jiān)聽狀態(tài)。在定時(shí)器激活后,如果有實(shí)體被加入到此線程的APC隊(duì)列中時(shí),Sleep()就會(huì)喚醒此線程。

            【示例代碼】

            #define _WIN32_WINNT 0x0500

            #include 
            <windows.h>
            #include 
            <stdio.h>

            #define _SECOND 10000000

            typedef 
            struct _MYDATA {
               TCHAR 
            *szText;
               DWORD dwValue;
            }
             MYDATA;

            VOID CALLBACK TimerAPCProc(
               LPVOID lpArg,               
            // Data value
               DWORD dwTimerLowValue,      // Timer low value
               DWORD dwTimerHighValue )    // Timer high value

            {
               MYDATA 
            *pMyData = (MYDATA *)lpArg;

               printf( 
            "Message: %s\nValue: %d\n\n", pMyData->szText,
                      pMyData
            ->dwValue );
               MessageBeep(
            0);

            }


            void main( void ) 
            {
               HANDLE          hTimer;
               BOOL            bSuccess;
               __int64         qwDueTime;
               LARGE_INTEGER   liDueTime;
               MYDATA          MyData;
               TCHAR           szError[
            255];

               MyData.szText 
            = "This is my data.";
               MyData.dwValue 
            = 100;

               
            if ( hTimer = CreateWaitableTimer(
                       NULL,                   
            // Default security attributes
                       FALSE,                  // Create auto-reset timer
                       "MyTimer" ) )           // Name of waitable timer
               {
                  __try 
                  
            {
                     
            // Create an integer that will be used to signal the timer 
                     
            // 5 seconds from now.
                     qwDueTime = -5 * _SECOND;

                     
            // Copy the relative time into a LARGE_INTEGER.
                     liDueTime.LowPart  = (DWORD) ( qwDueTime & 0xFFFFFFFF );
                     liDueTime.HighPart 
            = (LONG)  ( qwDueTime >> 32 );

                     bSuccess 
            = SetWaitableTimer(
                        hTimer,           
            // Handle to the timer object
                        &liDueTime,       // When timer will become signaled
                        2000,             // Periodic timer interval of 2 seconds
                        TimerAPCProc,     // Completion routine
                        &MyData,          // Argument to the completion routine
                        FALSE );          // Do not restore a suspended system

                     
            if ( bSuccess ) 
                     
            {
                        
            for ( ; MyData.dwValue < 1000; MyData.dwValue += 100 ) 
                        
            {
                           SleepEx(
                              INFINITE,     
            // Wait forever
                              TRUE );       // Put thread in an alertable state
                        }


                     }
             
                     
            else 
                     
            {
                        wsprintf( szError, 
            "SetWaitableTimer failed with Error \
                           %d.", GetLastError() );
                        MessageBox( NULL, szError, "Error", MB_ICONEXCLAMATION );
                     }


                  }
             
                  __finally 
                  
            {
                     CloseHandle( hTimer );
                  }

               }
             
               
            else 
               
            {
                  wsprintf( szError, 
            "CreateWaitableTimer failed with Error %d."
                      GetLastError() );
                  MessageBox( NULL, szError, 
            "Error", MB_ICONEXCLAMATION );
               }

            }

             

             

            原文參考:Using a Waitable Timer with an Asynchronous Procedure Call

            posted on 2011-06-02 17:15 楊粼波 閱讀(710) 評(píng)論(0)  編輯 收藏 引用


            只有注冊(cè)用戶登錄后才能發(fā)表評(píng)論。
            網(wǎng)站導(dǎo)航: 博客園   IT新聞   BlogJava   博問(wèn)   Chat2DB   管理


            日日狠狠久久偷偷色综合96蜜桃| 久久综合久久久| 国产成人香蕉久久久久 | 久久精品这里热有精品| 精品一区二区久久| 99久久夜色精品国产网站| 久久久WWW免费人成精品| 国产成人精品久久| 国产午夜精品久久久久免费视 | 99久久精品费精品国产| 久久久久久久波多野结衣高潮| 狠狠综合久久综合88亚洲| 久久香蕉一级毛片| 久久午夜无码鲁丝片秋霞 | 国产韩国精品一区二区三区久久| 国内精品伊人久久久久影院对白 | 亚洲一区精品伊人久久伊人| 欧美牲交A欧牲交aⅴ久久| 久久久精品人妻无码专区不卡| 香蕉久久夜色精品升级完成| 久久综合九色综合久99| AV无码久久久久不卡网站下载| 亚洲精品国产综合久久一线| 久久福利青草精品资源站| 香蕉久久久久久狠狠色| 18岁日韩内射颜射午夜久久成人| 无码精品久久久天天影视| 亚洲婷婷国产精品电影人久久| 精品久久久久久无码免费| 99久久777色| 久久精品一区二区国产| 亚洲精品国产美女久久久| 人人妻久久人人澡人人爽人人精品| 久久99国产亚洲高清观看首页 | 性做久久久久久久久久久| 精品久久人人做人人爽综合| 93精91精品国产综合久久香蕉| 久久精品一区二区三区不卡| 国产亚洲色婷婷久久99精品| 粉嫩小泬无遮挡久久久久久| 精品乱码久久久久久久|