• <strike id="fdgpu"><input id="fdgpu"></input></strike>
    <label id="fdgpu"></label>
    <s id="fdgpu"><code id="fdgpu"></code></s>

  • <label id="fdgpu"></label>
  • <span id="fdgpu"><u id="fdgpu"></u></span>

    <s id="fdgpu"><sub id="fdgpu"></sub></s>
    首頁 >> 新聞
     

    在Windows操作系統(tǒng)上
    以異步模式調(diào)用同步的
    Dialogic® Dialogic® 函數(shù)的
    解決方案

     
    • 概述
    • 緒言
    • 問題
    • 解決方案
      線程池
      為什么使用線程池
      Windows*線程池服務
      Windows線程池服務特性
      處理同步函數(shù)
      向應用程序發(fā)送通知
      平臺無關性
    • 應用實例
      應用場景
      應用程序初始化
      調(diào)用同步函數(shù)
      異步方式調(diào)用同步函數(shù)
      應用程序標準運行時事件循環(huán)
    • 結論

    概 述

      本應用手冊描述了在Windows操作系統(tǒng)上以異步方式調(diào)用Dialogic® Dialogic®同步函數(shù)的解決方案。首先講解線程及線程池,然后介紹一個會議應用的解決方案。

    緒 言

      本文檔介紹的方案普遍適用于任何一種耗時的,在完成之前阻塞其調(diào)用線程的函數(shù)。該方案在多線程的應用環(huán)境里利用Dialogic的標準運行時庫(SRL)進行事件管理。你可以使用任何事件管理機制來替代SRL,但是SRL提供了一個標準的方法來管理Dialogic?系統(tǒng)中的事件。

      想了解更多關于SRL的信息,請訪問:
    Voice Software Reference: Standard Runtime Library for Windows at
    http://www.Dialogic.com/

      請注意在試用本應用手冊里介紹的方案之前,建議讀者對同步函數(shù)的多線程安全性進行測試。本文所述方案僅適用于線程安全的同步函數(shù)。

    問 題

      絕大多數(shù)Dialogic Dialogic函數(shù)允許調(diào)用者選擇一種函數(shù)調(diào)用方式,分別是EV_SYNC(同步方式)和EV_ASYNC(異步方式)。但是有些函數(shù)只提供一種同步接口。同步函數(shù)在執(zhí)行過程中會阻塞調(diào)用它的線程或整個單線程的應用程序,直到函數(shù)返回。這種局限性成為了應用開發(fā)者非常關心的問題,特別是在高密度的系統(tǒng)中,某些同步函數(shù)非常耗時。這種耗時的函數(shù)限制了應用程序繼續(xù)處理其它的邏輯,而只能等待同步函數(shù)返回。

    圖 1. 同步和異步操作模式

    解決方案

      使用多線程可以異步的執(zhí)行同步函數(shù)。創(chuàng)建一個新的線程或使用一個已經(jīng)創(chuàng)建的線程作為工作線程,用來調(diào)用耗時的同步函數(shù)并等待其執(zhí)行和返回,而應用線程可以繼續(xù)處理后面的邏輯。當同步函數(shù)返回時,工作線程發(fā)布一個SRL事件(稍后說明)給應用線程,根據(jù)同步函數(shù)的返回值傳遞相應的返回碼。

      一種方法是預先創(chuàng)建一個工作線程池等待為主應用程序服務。這樣可以避免創(chuàng)建和結束動態(tài)線程的負荷。此時,線程池里的某個線程可能專門用于為池里的其它可用線程分配工作。

      下面的圖表闡述了這種解決方案的原理和好處。

      線程池

      本節(jié)介紹如何利用線程實現(xiàn)本篇應用手冊中建議的解決方案。

      為什么使用線程池

      如前所述,使用額外的線程可以讓主應用線程不必去等待同步函數(shù)的執(zhí)行。也就是說,應用程序可以繼續(xù)處理它的邏輯,而不會被執(zhí)行中的同步函數(shù)阻塞。

      但是如果額外的線程是在要調(diào)用同步函數(shù)的時候創(chuàng)建的,應用程序就要花費操作系統(tǒng)所需要的時間去創(chuàng)建這個線程。更好的解決方法是在應用程序初始化時預先創(chuàng)建一組工作線程,當應用程序需要時可以利用它們調(diào)用任何的同步函數(shù)。這個池里的工作線程需要由"某個人"來管理,為它們分派工作并保持負載平衡。因此在一個有"n"個工作線程的池里,你可以指定第一個線程作為主線程或者控制線程,其它?quot;n-1"個線程作為用來調(diào)用同步函數(shù)的工作線程。

      Windows*線程池服務

      Windows*本身就提供了由操作系統(tǒng)來進行管理的線程池技術。它根據(jù)應用程序的需要動態(tài)的創(chuàng)建和刪除線程。可創(chuàng)建的線程數(shù)僅受到系統(tǒng)內(nèi)存的限制。

      應用程序通過Windows的函數(shù)QueueUserWorkItem來使用線程池庫。當應用程序第一次調(diào)用這個函數(shù)時,Windows會創(chuàng)建線程池。池里至少會有一個線程被用來監(jiān)測其它的線程,并按照應用程序的需要為它們分配工作任務。

      預了解更多詳情,請訪問http://msdn.microsoft.com/library ,查找QueueUserWorkItem。

      Windows線程池服務特性

      Microsoft Visual Studio* 6.0版本提供的"winbase.h"里沒有包含函數(shù)QueueUserWorkItem的定義。開發(fā)者需要按如下所示手工定義這個函數(shù),或者在包含Visual Studio頭文件之前包含Windows SDK版本的"winbase.h"。

      處理同步函數(shù)

      任何同步函數(shù)要通過異步方式調(diào)用要開發(fā)一個開起來類似的函數(shù), 而且和同步函數(shù)有相同的參數(shù)。

      同步函數(shù):
      long foo(Type1 arg1, Type2 arg2 …, Typen argn)

      異步方式的同步函數(shù):
      long ASYNC_foo(Type1 arg1, Type2 arg2 …, Typen argn);

      按如下所示定義一個結構用來封裝函數(shù)的參數(shù)并傳遞給線程池。如果任何一個形式參數(shù)是指針類型的變量,要確保同步函數(shù)在工作線程中執(zhí)行時該指針是有效的。
      typedef struct tagFOO {
       Type1 arg1;
       Type2 arg2;
       .
       .
       .
       Typen argn;
      } DFOO, *PFOO;

      應用程序按如下所示調(diào)用Dialogic函數(shù):
      // asynchronous invocation
      if (invokeAsynchronously)
      {
        rc = ASYNC_foo(arg1, arg2, … , argn);
      }
      // synchronous invocation
      else
      {
        rc = foo(arg1, arg2, … , argn);
      }

        };
        PFOO pvContext = new DFOO (vContext);
        QueueUserWorkItem(THREAD_ASYNC_foo, pvContext,
           WT_EXECUTEINLONGTHREAD);
        return 0;
      }


      THREAD_ASYNC_foo是回調(diào)函數(shù),會被Windows線程池服務選擇的工作線程調(diào)用。

      回調(diào)函數(shù)的實現(xiàn)方法:

      #define ASYNC_EVENT_FOO 0x10000
      void THREAD_ASYNC_foo(void* pvContext)
      {
        long rc = 0;
        PFOO pContext = (PFOO)pvContext;
        rc = foo(pContext->arg1, pContext->arg2, …, pContext->argn);
        // the synchronous function has returned;
        // post an event to the appln
        sr_putevt(devh, ASYNC_EVENT_FOO, sizeof(rc), &rc, 0);
        delete pContext;
      }


      ASYNC_EVENT_FOO是同步函數(shù)foo完成時發(fā)布給應用程序的SRL用戶事件。實際上foo確實是以同步方式調(diào)用的,但是現(xiàn)在僅有線程池中被選中的線程用來等待該函數(shù)完成,而應用程序則可以不受限制的繼續(xù)處理它的邏輯。

      形式參數(shù)被封裝在一個結構里,其占用內(nèi)存是在程序片斷里動態(tài)分配和釋放的。在高密度系統(tǒng)中,可以使用緩沖池來預先分配內(nèi)存從而避免動態(tài)分配和釋放內(nèi)存的負荷。

      向應用程序發(fā)送通知

      同步函數(shù)完成時,工作線程通過SRL提供的事件發(fā)布技術通知應用程序。其它的事件管理方法也可以用來達到這一目的。

      SRL主要的功能是提供事件管理的通用接口和所有Dialogic設備的通用功能。SRL負責集中的分發(fā)所有Dialogic設備上產(chǎn)生的事件。通過SRL,能夠以一種標準的方式處理事件。

      同步函數(shù)完成后,THREAD_ASYNC_foo回調(diào)函數(shù)使用SRL函數(shù)sr_putevt向應用程序發(fā)布一個預定義的事件。

      // return code
      long rc;
      rc = foo(…);
      sr_putevt(devh, ASYNC_EVENT_FOO, sizeof(rc), &rc, 0);

      應用程序接著使用某個SRL等待函數(shù)來等待SRL事件,例如如下所示的sr_waitevt,該函數(shù)在指定的時間段內(nèi)等待任何事件。

      // loop infinitely
      while (1)
      {

      函數(shù)ProcessEvents為應用程序管理事件。所有在應用程序的SRL事件循環(huán)中接收到的事件都是在這個函數(shù)里處理的。該函數(shù)僅對接收到的事件進行分析和執(zhí)行事件相關的處理。

      平臺無關性

      本應用手冊介紹的解決方案是在Windows上實現(xiàn)的。你可以開發(fā)一個平臺無關的線程池庫,這樣應用程序就不用關心底層是什么操作系統(tǒng)了。如果是Windows,這個庫可以利用Windows自帶的線程池服務;如果是其它的操作系統(tǒng),可能要自行實現(xiàn)線程池技術。

    應用實例

      本應用手冊介紹的解決方案是以一個會議應用為實例的。這個應用程序有兩個參數(shù)。
      模式: 0 = 同步; 1 = 異步
      會議方數(shù)

      應用場景

      應用程序創(chuàng)建一個用戶提供方數(shù)的會議。第一方播放一個文件,其余各方錄制該文件。應用程序運行在異步模式演示了異步調(diào)用方式。函數(shù)dcb_estconf和dcb_addtoconf例證了這種方案。這兩個函數(shù)是Dialogic R4 API的一部分,它們只能提供同步的調(diào)用模式。但是這個應用程序演示了一個開發(fā)者如何用異步方式來調(diào)用這些函數(shù)。

      應用程序初始化

      int main(int argc, char* argv[])
      {
        int iIndex = 0;
        short iIterator = 0; // to access global arrays
        // collect command line parameters
        .
        .
        .
        if (async)
        {
          // initiale thread pool library
          .
          .
          .
        }

      }

      調(diào)用同步函數(shù)

      每個同步函數(shù)foo的異步形勢可能是ASYNC_foo。兩種函數(shù)應該有相同形勢的參數(shù)。

      if (async)
      {

      }

      異步方式調(diào)用時,返回碼僅表示這項工作已被成功的傳遞給工作線程。實際的錯誤返回碼將在同步函數(shù)完成時由工作線程發(fā)送到應用程序的事件循環(huán)里。

      異步方式調(diào)用同步函數(shù)

      為了完成讓工作線程調(diào)用同步函數(shù)的任務,異步形勢的函數(shù)必須把函數(shù)參數(shù)封裝在一個結構里,為這個結構分配內(nèi)存,然后使用Windows API QueueUserWorkItem把一項用戶工作發(fā)送給線程池庫。

      typedef struct tagDCB_ESTCONF {
        int devh;
        MS_CDT* cdt;
        int numpty
        int confattr;
        int* confid;
      } DCB_ESTCONF, *PDCB_ESTCONF;
      long WINAPI ASYNC_dcb_estconf(int devh, MS_CDT* cdt, int numpty,
        int confattr, int* confid)
      {
        DCB_ESTCONF vContext = {
        devh,
        cdt,
        numpty,
        confattr,
        confid

        QueueUserWorkItem(THREAD_ASYNC_dcb_estconf, pvContext,
                       WT_EXECUTEINLONGTHREAD);
        return 0;
      }
      void THREAD_ASYNC_dcb_estconf(void* pvContext)
      {
        long rc = 0; PDCB_ESTCONF pContext = (PDCB_ESTCONF)pvContext;
        rc = dcb_estconf(pContext->devh, pContext->cdt, pContext->numpty,     
                      pContext->confattr, pContext->confid);
        sr_putevt(pContext->devh, DCB_EVENT_ESTCONF, sizeof(rc), &rc, 0); delete pContext;
      }


      應用程序標準運行時事件循環(huán)


      下面這段代碼提供了本應用手冊所討論的會議應用的事件管理實例。

      void ProcessEvents()
      {
        long ev;
        void* vp;

    結 論

      在一個簡單的32方會議應用實例的測試運行中,同步模式調(diào)用阻塞了應用程序達3545毫秒。與此相反,異步模式僅僅阻塞了應用程序421毫秒。換言之,本應用手冊介紹的方案幫助應用程序以相當于同步方式12%的時間處理了同步函數(shù)。在大多數(shù)應用中,這段寶貴的時間可以用來處理其它的應用邏輯。該測試系統(tǒng)的規(guī)范如下:

    • 系統(tǒng)版本: Dialogic Dialogic SR 5.1.1 FP1 for Windows
    • 操作系統(tǒng): Windows 2000 SP 3
    • 處理器速度: 500 MHz
    • 內(nèi)存: 128 MB
    • Dialogic Dialogic板卡: DM/V1200A-4E1, DM/V1200-4E1

      與了解更多詳情,請訪問Dialogic網(wǎng)站http://www.Dialogic.com/.

     


    [ 全文英文版 ]

     




    融合通信專欄>>技術開發(fā)>>

     
     

    相關頻道:           文摘

    亚洲精品网站在线观看不卡无广告,国产a不卡片精品免费观看,欧美亚洲一区二区三区在线,国产一区二区三区日韩 彭阳县| 洪洞县| 五河县| 鹿泉市| 山东省| 江孜县| 平泉县| 上栗县| 郸城县| 郁南县| 密云县| 榆林市| 沁水县| 金坛市| 财经| 江津市| 沂南县| 文水县| 商水县| 静海县| 邵东县| 黄大仙区| 枣阳市| 贡山| 招远市| 白银市| 庆元县| 丹寨县| 嘉义县| 屯留县| 栾川县| 古蔺县| 南溪县| 忻城县| 比如县| 潼关县| 河北区| 富蕴县| 安西县| 大英县| 霍山县| http://444 http://444 http://444 http://444 http://444 http://444