程序師世界是廣大編程愛好者互助、分享、學習的平台,程序師世界有你更精彩!
首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫知識
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
 程式師世界 >> 編程語言 >> .NET網頁編程 >> .NET實例教程 >> 用戶模式異步過程調用(APC)

用戶模式異步過程調用(APC)

編輯:.NET實例教程

以前對User-Mode APC不甚了解, 最近在看一個開源項目時看到了對APC的使用。看來多看代碼的確是有好處地:)廢話不多說。我們來看看APC的真面目吧。

APC即asynchronous procedure call,每一線程都有一個APC隊列。操作系統 允許一個應用向一個指定線程的APC隊列中放入APC函數。當指定的線程處於警告狀態時,該線程就會調用隊列中的APC函數。調用的順序為先入先出(FIFO)。可以用以下函數使一個線程進入警告狀態:

SleepEx, SignalObjectAndWait, WaitForSingleObjectEx, WaitForMultipleObjectsEx, MsgWaitForMultipleObjectsEx

一句話,就是可以讓別的線程執行一個函數。下面是一段例子



LRESULT CALLBACK APCWndProc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam)
{
    if (msg==WM_NULL) SleepEx(0,TRUE);
    return DefWindowProc(hwnd,msg,wParam,lParam);
}

//主線程調用
BOOL Initialize()
{
    DuplicateHandle(GetCurrentProcess(),
              GetCurrentThread(),
              GetCurrentProcess(),
              &g_hMainThread,
              THREAD_SET_CONTEXT,
              FALSE,
              0);
                     //為了讓APC盡快響應,創建窗口,在WM_NULL中調用SleepEx讓線程進入警告狀態。
    g_hAPCWnd = CreateWindowEx(0,_T("STATIC"),NULL,0, 0,0,0,0, NULL,NULL,NULL,NULL);
    SetWindowLongPtr(m_hACPWnd, GWL_WNDPROC, (LONG)(LONG_PTR)APCWndProc);
    return TRUE;
}

//工作者線程調用
int  CallFunctionAsync(void (__stdcall *func)(void *), void *arg)
{
    int res = 0;
    res = QueueUserAPC((void (__stdcall *)(DWORD))func, g_hMainThread, (DWord_PTR)arg);
    PostMessage(g_hAPCWnd, WM_NULL, 0, 0);
  return res;
}

主線程調用Initialize來創建APCWnd,以及保存主線程句柄。為了使APC能夠及時響應創建APCWnd,工作者線程調用CallFunctionAsync讓主線程運行 func函數指針指向的函數,在該函數中向APCWnd發送WM_NULL消息,窗口過程在響應該消息時調用SleepEx使線程進入警告狀態,從而檢查並調用APC隊列中的APC函數。這樣就實現了一個讓已知的線程調用指定的函數。

  1. 上一頁:
  2. 下一頁:
Copyright © 程式師世界 All Rights Reserved