- 概述
- 緒言
- 問題
- 解決方案
線程池
為什么使用線程池
Windows*線程池服務(wù)
Windows線程池服務(wù)特性
處理同步函數(shù)
向應(yīng)用程序發(fā)送通知
平臺(tái)無關(guān)性
- 應(yīng)用實(shí)例
應(yīng)用場(chǎng)景
應(yīng)用程序初始化
調(diào)用同步函數(shù)
異步方式調(diào)用同步函數(shù)
應(yīng)用程序標(biāo)準(zhǔn)運(yùn)行時(shí)事件循環(huán)
- 結(jié)論
■ 概 述
本應(yīng)用手冊(cè)描述了在Windows操作系統(tǒng)上以異步方式調(diào)用Dialogic® Dialogic®同步函數(shù)的解決方案。首先講解線程及線程池,然后介紹一個(gè)會(huì)議應(yīng)用的解決方案。
■ 緒 言
本文檔介紹的方案普遍適用于任何一種耗時(shí)的,在完成之前阻塞其調(diào)用線程的函數(shù)。該方案在多線程的應(yīng)用環(huán)境里利用Dialogic的標(biāo)準(zhǔn)運(yùn)行時(shí)庫(SRL)進(jìn)行事件管理。你可以使用任何事件管理機(jī)制來替代SRL,但是SRL提供了一個(gè)標(biāo)準(zhǔn)的方法來管理Dialogic?系統(tǒng)中的事件。
想了解更多關(guān)于SRL的信息,請(qǐng)?jiān)L問:
http://www.Dialogic.com/
請(qǐng)注意在試用本應(yīng)用手冊(cè)里介紹的方案之前,建議讀者對(duì)同步函數(shù)的多線程安全性進(jìn)行測(cè)試。本文所述方案僅適用于線程安全的同步函數(shù)。
■ 問 題
絕大多數(shù)Dialogic Dialogic函數(shù)允許調(diào)用者選擇一種函數(shù)調(diào)用方式,分別是EV_SYNC(同步方式)和EV_ASYNC(異步方式)。但是有些函數(shù)只提供一種同步接口。同步函數(shù)在執(zhí)行過程中會(huì)阻塞調(diào)用它的線程或整個(gè)單線程的應(yīng)用程序,直到函數(shù)返回。這種局限性成為了應(yīng)用開發(fā)者非常關(guān)心的問題,特別是在高密度的系統(tǒng)中,某些同步函數(shù)非常耗時(shí)。這種耗時(shí)的函數(shù)限制了應(yīng)用程序繼續(xù)處理其它的邏輯,而只能等待同步函數(shù)返回。
■ 解決方案
使用多線程可以異步的執(zhí)行同步函數(shù)。創(chuàng)建一個(gè)新的線程或使用一個(gè)已經(jīng)創(chuàng)建的線程作為工作線程,用來調(diào)用耗時(shí)的同步函數(shù)并等待其執(zhí)行和返回,而應(yīng)用線程可以繼續(xù)處理后面的邏輯。當(dāng)同步函數(shù)返回時(shí),工作線程發(fā)布一個(gè)SRL事件(稍后說明)給應(yīng)用線程,根據(jù)同步函數(shù)的返回值傳遞相應(yīng)的返回碼。
一種方法是預(yù)先創(chuàng)建一個(gè)工作線程池等待為主應(yīng)用程序服務(wù)。這樣可以避免創(chuàng)建和結(jié)束動(dòng)態(tài)線程的負(fù)荷。此時(shí),線程池里的某個(gè)線程可能專門用于為池里的其它可用線程分配工作。
下面的圖表闡述了這種解決方案的原理和好處。
線程池
本節(jié)介紹如何利用線程實(shí)現(xiàn)本篇應(yīng)用手冊(cè)中建議的解決方案。
為什么使用線程池
如前所述,使用額外的線程可以讓主應(yīng)用線程不必去等待同步函數(shù)的執(zhí)行。也就是說,應(yīng)用程序可以繼續(xù)處理它的邏輯,而不會(huì)被執(zhí)行中的同步函數(shù)阻塞。
但是如果額外的線程是在要調(diào)用同步函數(shù)的時(shí)候創(chuàng)建的,應(yīng)用程序就要花費(fèi)操作系統(tǒng)所需要的時(shí)間去創(chuàng)建這個(gè)線程。更好的解決方法是在應(yīng)用程序初始化時(shí)預(yù)先創(chuàng)建一組工作線程,當(dāng)應(yīng)用程序需要時(shí)可以利用它們調(diào)用任何的同步函數(shù)。這個(gè)池里的工作線程需要由"某個(gè)人"來管理,為它們分派工作并保持負(fù)載平衡。因此在一個(gè)有"n"個(gè)工作線程的池里,你可以指定第一個(gè)線程作為主線程或者控制線程,其它?quot;n-1"個(gè)線程作為用來調(diào)用同步函數(shù)的工作線程。
Windows*線程池服務(wù)
Windows*本身就提供了由操作系統(tǒng)來進(jìn)行管理的線程池技術(shù)。它根據(jù)應(yīng)用程序的需要?jiǎng)討B(tài)的創(chuàng)建和刪除線程。可創(chuàng)建的線程數(shù)僅受到系統(tǒng)內(nèi)存的限制。
應(yīng)用程序通過Windows的函數(shù)QueueUserWorkItem來使用線程池庫。當(dāng)應(yīng)用程序第一次調(diào)用這個(gè)函數(shù)時(shí),Windows會(huì)創(chuàng)建線程池。池里至少會(huì)有一個(gè)線程被用來監(jiān)測(cè)其它的線程,并按照應(yīng)用程序的需要為它們分配工作任務(wù)。
預(yù)了解更多詳情,請(qǐng)?jiān)L問
,查找QueueUserWorkItem。
Windows線程池服務(wù)特性
Microsoft Visual Studio* 6.0版本提供的"winbase.h"里沒有包含函數(shù)QueueUserWorkItem的定義。開發(fā)者需要按如下所示手工定義這個(gè)函數(shù),或者在包含Visual
Studio頭文件之前包含Windows SDK版本的"winbase.h"。
處理同步函數(shù)
任何同步函數(shù)要通過異步方式調(diào)用要開發(fā)一個(gè)開起來類似的函數(shù), 而且和同步函數(shù)有相同的參數(shù)。
同步函數(shù):
異步方式的同步函數(shù):
按如下所示定義一個(gè)結(jié)構(gòu)用來封裝函數(shù)的參數(shù)并傳遞給線程池。如果任何一個(gè)形式參數(shù)是指針類型的變量,要確保同步函數(shù)在工作線程中執(zhí)行時(shí)該指針是有效的。
應(yīng)用程序按如下所示調(diào)用Dialogic函數(shù):
THREAD_ASYNC_foo是回調(diào)函數(shù),會(huì)被Windows線程池服務(wù)選擇的工作線程調(diào)用。
回調(diào)函數(shù)的實(shí)現(xiàn)方法:
ASYNC_EVENT_FOO是同步函數(shù)foo完成時(shí)發(fā)布給應(yīng)用程序的SRL用戶事件。實(shí)際上foo確實(shí)是以同步方式調(diào)用的,但是現(xiàn)在僅有線程池中被選中的線程用來等待該函數(shù)完成,而應(yīng)用程序則可以不受限制的繼續(xù)處理它的邏輯。
形式參數(shù)被封裝在一個(gè)結(jié)構(gòu)里,其占用內(nèi)存是在程序片斷里動(dòng)態(tài)分配和釋放的。在高密度系統(tǒng)中,可以使用緩沖池來預(yù)先分配內(nèi)存從而避免動(dòng)態(tài)分配和釋放內(nèi)存的負(fù)荷。
向應(yīng)用程序發(fā)送通知
同步函數(shù)完成時(shí),工作線程通過SRL提供的事件發(fā)布技術(shù)通知應(yīng)用程序。其它的事件管理方法也可以用來達(dá)到這一目的。
SRL主要的功能是提供事件管理的通用接口和所有Dialogic設(shè)備的通用功能。SRL負(fù)責(zé)集中的分發(fā)所有Dialogic設(shè)備上產(chǎn)生的事件。通過SRL,能夠以一種標(biāo)準(zhǔn)的方式處理事件。
同步函數(shù)完成后,THREAD_ASYNC_foo回調(diào)函數(shù)使用SRL函數(shù)sr_putevt向應(yīng)用程序發(fā)布一個(gè)預(yù)定義的事件。
應(yīng)用程序接著使用某個(gè)SRL等待函數(shù)來等待SRL事件,例如如下所示的sr_waitevt,該函數(shù)在指定的時(shí)間段內(nèi)等待任何事件。
函數(shù)ProcessEvents為應(yīng)用程序管理事件。所有在應(yīng)用程序的SRL事件循環(huán)中接收到的事件都是在這個(gè)函數(shù)里處理的。該函數(shù)僅對(duì)接收到的事件進(jìn)行分析和執(zhí)行事件相關(guān)的處理。
平臺(tái)無關(guān)性
本應(yīng)用手冊(cè)介紹的解決方案是在Windows上實(shí)現(xiàn)的。你可以開發(fā)一個(gè)平臺(tái)無關(guān)的線程池庫,這樣應(yīng)用程序就不用關(guān)心底層是什么操作系統(tǒng)了。如果是Windows,這個(gè)庫可以利用Windows自帶的線程池服務(wù);如果是其它的操作系統(tǒng),可能要自行實(shí)現(xiàn)線程池技術(shù)。
■ 應(yīng)用實(shí)例
本應(yīng)用手冊(cè)介紹的解決方案是以一個(gè)會(huì)議應(yīng)用為實(shí)例的。這個(gè)應(yīng)用程序有兩個(gè)參數(shù)。
模式: 0 = 同步; 1 = 異步
會(huì)議方數(shù)
應(yīng)用場(chǎng)景
應(yīng)用程序創(chuàng)建一個(gè)用戶提供方數(shù)的會(huì)議。第一方播放一個(gè)文件,其余各方錄制該文件。應(yīng)用程序運(yùn)行在異步模式演示了異步調(diào)用方式。函數(shù)dcb_estconf和dcb_addtoconf例證了這種方案。這兩個(gè)函數(shù)是Dialogic
R4 API的一部分,它們只能提供同步的調(diào)用模式。但是這個(gè)應(yīng)用程序演示了一個(gè)開發(fā)者如何用異步方式來調(diào)用這些函數(shù)。
應(yīng)用程序初始化
調(diào)用同步函數(shù)
每個(gè)同步函數(shù)foo的異步形勢(shì)可能是ASYNC_foo。兩種函數(shù)應(yīng)該有相同形勢(shì)的參數(shù)。
異步方式調(diào)用時(shí),返回碼僅表示這項(xiàng)工作已被成功的傳遞給工作線程。實(shí)際的錯(cuò)誤返回碼將在同步函數(shù)完成時(shí)由工作線程發(fā)送到應(yīng)用程序的事件循環(huán)里。
異步方式調(diào)用同步函數(shù)
為了完成讓工作線程調(diào)用同步函數(shù)的任務(wù),異步形勢(shì)的函數(shù)必須把函數(shù)參數(shù)封裝在一個(gè)結(jié)構(gòu)里,為這個(gè)結(jié)構(gòu)分配內(nèi)存,然后使用Windows
API QueueUserWorkItem把一項(xiàng)用戶工作發(fā)送給線程池庫。
應(yīng)用程序標(biāo)準(zhǔn)運(yùn)行時(shí)事件循環(huán)
下面這段代碼提供了本應(yīng)用手冊(cè)所討論的會(huì)議應(yīng)用的事件管理實(shí)例。
■ 結(jié) 論
在一個(gè)簡(jiǎn)單的32方會(huì)議應(yīng)用實(shí)例的測(cè)試運(yùn)行中,同步模式調(diào)用阻塞了應(yīng)用程序達(dá)3545毫秒。與此相反,異步模式僅僅阻塞了應(yīng)用程序421毫秒。換言之,本應(yīng)用手冊(cè)介紹的方案幫助應(yīng)用程序以相當(dāng)于同步方式12%的時(shí)間處理了同步函數(shù)。在大多數(shù)應(yīng)用中,這段寶貴的時(shí)間可以用來處理其它的應(yīng)用邏輯。該測(cè)試系統(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
與了解更多詳情,請(qǐng)?jiān)L問Dialogic網(wǎng)站http://www.Dialogic.com/.
[ 全文英文版
]
|