摘要:該文借鑒I/O完成端口模型(IOCP)的核心思想,建立了一個適用于協(xié)議性串口通訊的新模型。該模型提出了一個協(xié)議性串口通訊的最小單位——“通訊元”,將“通訊元”提交到事件隊列線程中自動處理,簡化了處理過程并提高了運行效率。同時,該文基于該模型設(shè)計出了一個協(xié)議性串口通訊模塊,以封裝通訊底層的細(xì)節(jié),從而提供方便的通訊接口。將該模塊應(yīng)用于工業(yè)造氣爐監(jiān)控組態(tài)軟件設(shè)計中,實際運行表明:該模型具有簡單的接口和穩(wěn)定、高效的運行機制。
關(guān)鍵詞:IOCP;串口通訊;通訊元
中圖分類號:TN915 文獻(xiàn)標(biāo)識碼:A 文章編號:1009-3044(2013)04-0689-04
The Research and Application of a New Serial Communication Model
CHEN Geng
(College of Information Science & Technology, Xiamen University, Xiamen 361005, China)
Abstract: In this paper, the core idea of I/O Completion Port Model is borrowed to build a new model, which is suitable for the serial communication based on protocol. A minimum unit called ‘communication unit’ is put forward in this model. The ‘communication unit’ is submitted to an event-queue-thread and is dealt automatically. It will help to simplify the process and increase operational efficiency. Meanwhile, in this paper, a serial communication module based on the model is designed to offer a convenient communication interface. The module is applied in the snoopware of industrial gasifier. It’s proved that this model has a simple interface and efficient operation mechanism.
Key words: IOCP; serial communication; communication unit
Web服務(wù)器、網(wǎng)絡(luò)游戲服務(wù)器等應(yīng)用經(jīng)常會面對海量的客戶端連接請求以及數(shù)據(jù)通信,這種海量的并發(fā)的連接請求與數(shù)據(jù)通信,往往成為制約服務(wù)器正常工作的因素。這些與服務(wù)器的數(shù)據(jù)傳輸具有共同的特點:客戶連接量是海量的,但每個連接上收發(fā)的數(shù)據(jù)包容量是較小的。微軟公司在Winsock2中引入的完成端口(Completion Port,IOCP)模型提供了最好的伸縮性和最高的數(shù)據(jù)吞吐率,是處理大量并發(fā)連接的最佳方案。
在上位機與多臺下位機通過串口通信的環(huán)境中,隨著連接數(shù)的增多,系統(tǒng)通信的速度降低,通信錯誤率增加,如何有效的管理和協(xié)調(diào)眾多線程,是一個比較困難的問題。該文基于IOCP核心思想提出了一個通訊元模型,并針對實際應(yīng)用設(shè)計了一個支持多串口通訊模塊。該模塊應(yīng)用于工業(yè)造氣爐監(jiān)控組態(tài)軟件設(shè)計中,實際運行表明:該模型具有簡單的接口和穩(wěn)定、高效的運行機制。
1 I/O完成端口模型(IOCP)簡介
1.1完成端口
完成端口是Windows提供的一種高效的I/O模型,它利用少量的工作線程來完成大量的異步I/O處理,使得I/O處理和非I/O處理能夠重疊并行的進行,從而滿足大并發(fā)量管理工作。完成端口的目標(biāo)就是利用多線程來最大化提高并行執(zhí)行的效率,避免線程上不必要的阻塞,減少線程上下文切換帶來的資源和時間開銷。
1.2完成端口工作原理
完成端口會創(chuàng)建一個消息隊列和一個線程池。根據(jù)計算機系統(tǒng)中的處理器數(shù)目,建立相應(yīng)的工作者線程,這些線程專門用來處理和客戶端通信。當(dāng)客戶端建立新的socket連接時,該socket連接的句柄就與完成端口綁定起來。該socket的網(wǎng)絡(luò)通信請求按照先進先出的方式進入到完成端口的消息隊列中去。線程池取出空閑的線程,讓線程掃描完成端口中的消息隊列,取出隊列里面的通信請求(如發(fā)送數(shù)據(jù)、接收數(shù)據(jù))并處理。等處理完畢后再掃描隊列里面的下一個網(wǎng)絡(luò)通信請求,如此循環(huán)。
需要注意的是,完成端口對工作線程的管理具有一定的原則:首先在創(chuàng)建完成端口時要制定最大的并發(fā)線程數(shù)(補充的后文流程),一般情況是一個處理器對應(yīng)一個并發(fā)線程,而工作線程的數(shù)量大于或等于最大并發(fā)線程書??紤]到線程會進入掛起的狀態(tài),為了讓應(yīng)用程序有足夠的工作線程為I/O請求服務(wù),一般創(chuàng)建工作線程的個數(shù)為CPU個數(shù)的兩倍。
1.3完成端口優(yōu)勢
多線程的方式來處理客戶端的socket通信請求,每一個客戶端要求連入socket時,都要啟動一個新的線程與客戶端進行通信。CPU不得不在運行的線程之間進行上下文的切換。因為線程切換是相當(dāng)占用CPU時間的,當(dāng)客戶端的連入線程過多時,CPU的執(zhí)行效率將變得非常低下。微軟提出完成端口模型,就是為了解決“one-treat-per-client”的問題。完成端口模型能夠在只有少量工作者線程的情況下處理大量的socket操作,從而避免多線程造成的線程切換開銷,最大限度的提高了網(wǎng)絡(luò)通信的性能。
2 協(xié)議性串口通訊的新模型
2.1 串口通信的一般方式
串口編程有阻塞和非阻塞兩種方式。阻塞方式是指在調(diào)用函數(shù)后,當(dāng)前線程會被掛起直到接收到數(shù)據(jù)。非阻塞方式指在調(diào)用函數(shù)后,該函數(shù)不會阻塞當(dāng)前線程,而會立刻返回,線程可以繼續(xù)進行其他操作。阻塞模型編程比較簡單,但是執(zhí)行效率低下,適合于并發(fā)連接數(shù)較少的系統(tǒng)。非阻塞模型編程難度比較大,但是程序執(zhí)行效率高,適合于連接數(shù)大性能的系統(tǒng)。
除了效率問題之外,串口通信時經(jīng)常會線程超時和串口堵塞問題。特別是在多串口通信中。這兩種問題,可以通過程序設(shè)計來解決,但這樣又增加了程序設(shè)計的難度。如果有一種模型,從結(jié)構(gòu)上來解決效率問題,又能解決超時和數(shù)據(jù)堵塞問題,那這種模型將有深遠(yuǎn)的意義。
2.2 串口通信的新模型
該模型基于I/O完成端口模型(IOCP)的核心思想,提出了一個協(xié)議性串口通訊的最小單位——“通訊元”,每個“通訊元”包括“發(fā)送的命令(數(shù)據(jù))”、“等待接收的命令(數(shù)據(jù))長度”、“超時處理函數(shù)的綁定”、“接收數(shù)據(jù)處理函數(shù)的綁定”等部分組成。“通訊元”相當(dāng)于IOCP中的消息一樣,會被提交到事件隊列中。一個“通訊元”執(zhí)行過程中,事件隊列線程掛起,等待“通訊元”完成。
“通訊元”結(jié)構(gòu)利用了設(shè)計模式中的Composite模式(組合模式)的思想,將每次通訊底層的細(xì)節(jié)封裝起來,對外提供方便的通訊接口。發(fā)送數(shù)據(jù)對象、接收數(shù)據(jù)對象、超時處理對象、數(shù)據(jù)處理對象與通訊元接口是聚合關(guān)系,且是一對多關(guān)系。這種設(shè)計結(jié)構(gòu)有利于方便的為通訊元添加其他通訊相關(guān)的對象,使得通訊的處理過程更加簡化高效,同時使得程序有更強的可移植性。
2.3 新模型工作機制
圖2 新模型機制
程序主線程啟動后,開啟通訊元引擎,進行串口的初始化和通訊元的初始化。通訊元引擎創(chuàng)建通訊元的接收隊列、發(fā)送隊列、消息處理隊列和超時處理隊列。當(dāng)串口發(fā)生通訊操作時,工作者線程啟動,通訊元進入消息隊列。工作者線程按照先進先出的原則,提取隊頭的通訊元,再從線程池中取出空閑的線程,在空閑線程中依次判斷通信元是否與處理函數(shù)相綁定,是否處于發(fā)送或接收等待狀態(tài),是否已經(jīng)超時,并對各種狀態(tài)進行相應(yīng)處理,最后將無效的通訊元清除。如此循環(huán)往復(fù)。
3 串口通訊新模塊的設(shè)計
3.1 多串口通信結(jié)構(gòu)
為安徽某公司設(shè)計的工業(yè)造氣爐監(jiān)控組態(tài)軟件,是基于多串口的通信結(jié)構(gòu)。上位機通過擴展配備多個串口與多臺下位機通信。每臺下位機負(fù)責(zé)采集或控制其監(jiān)控對象的運行狀態(tài)。一方面上位機通過串口向多臺下位機發(fā)送控制命令,另一方面多臺下位機通過串口向上位機發(fā)送狀態(tài)信息。應(yīng)用程序中采用了通訊元串口通信模塊。
圖3 多串口通信模型
多串口通信面臨的最主要問題就是并發(fā)處理問題。上位機是單一串口,通過多串口擴展器與多臺下位機連接。上位機有可能同時向多臺下位機發(fā)出控制命令,多臺下位機也有可能同時向上位機發(fā)送反饋信息。這樣使得程序設(shè)計變得很復(fù)雜,一旦程序設(shè)計的邏輯考慮不夠全面,就很有可能造成信息混亂。而基于IOCP的通信元模型的就很好的解決了這個問題。無論是上位機發(fā)送控制命令,還是下位機發(fā)送反饋信息,都將在程序中生成一個通信元,每個通信元里面都記錄著對應(yīng)下位機的信息,這樣就確保了上位機能夠準(zhǔn)確的發(fā)送和接收到指定下位機的信息,提高了通信的準(zhǔn)確率。
3.2 程序設(shè)計流程
圖4 程序流程圖
系統(tǒng)由一個主線程和指定數(shù)目的工作者線程組成。主線程主要完成的工作是:通信模塊的初始化,通信元隊列的創(chuàng)建,工作者線程的創(chuàng)建,串口操作的獲取,通信元的入隊以及程序退出時資源的釋放。通信元產(chǎn)生時要先標(biāo)記自身的狀態(tài)。狀態(tài)包括下位機的ID號,該通信元是發(fā)送信息通信元或者是接收信息通信元。同時,程序還要初始化通信元的數(shù)據(jù)容量,將要發(fā)送或接收的數(shù)據(jù)裝入通信元中。最后標(biāo)記通信元的超時處理方式,包括上位機重新發(fā)送,下位機重新發(fā)送以及不做任何處理。重新發(fā)送也包括重新發(fā)送一次或者重新發(fā)送直到發(fā)送成功。
工作者線程的作用是實現(xiàn)異步操作。主要完成的工作:從通信元隊列中取出通信元,首先判斷通信元是否處于超時狀態(tài),在不處于超時狀態(tài)的情況下,解析通信元的當(dāng)前狀態(tài),并對各種狀態(tài)進行相應(yīng)處理,最后將無效的通訊元清除。工作者線程是多線程并行工作的。程序先掃描線程池中線程的狀態(tài),取出一條空閑的線程??臻e線程從通信元隊列中取出第一個通信元進行解析。在解析通信元狀態(tài)時,上位機將首先獲取該通信元所對應(yīng)的下位機信息,以保證上位機能夠準(zhǔn)確的與對應(yīng)的下位機通信。當(dāng)通信元狀態(tài)為發(fā)送狀態(tài)時,程序先判斷串口緩沖區(qū)是否為空,當(dāng)串口緩沖區(qū)為空時執(zhí)行該通信元。當(dāng)通信元狀態(tài)為接收通信元時,當(dāng)前線程會先掛起,等待該通信元所指定的下位機發(fā)送信息。當(dāng)通信元狀態(tài)為處理狀態(tài)時,程序?qū)⒄{(diào)用解析函數(shù)來得到通信元中的數(shù)據(jù)。當(dāng)通信元被標(biāo)記為無效時,程序?qū)h掉該通信元。
3.3 實驗仿真
表1 模型的開銷對比
由于受到串口等硬件條件的限制,所做的實驗是通過串口仿真軟件來完成的。主機配置是CPU:AMD Athlon Dual-Core M320 2.10GHz, RAM 3.00GB,在串口仿真軟件中設(shè)置虛擬串口的數(shù)目。實驗?zāi)M向每個串口發(fā)起連接,并完成一次收發(fā)工作。
實驗結(jié)果表明:基于通信元新模型的服務(wù)端在接收相同連接數(shù)時所消耗的時間比傳統(tǒng)模型要少,隨著連接數(shù)的增多,優(yōu)勢更加明顯。主要原因通信元模型使用很少的線程,而傳統(tǒng)模型每個連接都要創(chuàng)建一個線程。CPU沒有在多線程中頻繁的切換,因此CPU資源開銷很少,系統(tǒng)執(zhí)行速度就快了很多。但可以看到基于通信元新模型的服務(wù)端在內(nèi)存開銷上比傳統(tǒng)模型要大。這是因為通信元隊列中每個通信元都要開辟一塊內(nèi)存空間來存儲數(shù)據(jù),當(dāng)通訊量很大時,內(nèi)存的占用量就會很高。但是對于上位機來說,增加內(nèi)存是非常方便的事情。通過消耗更多的內(nèi)存來提高系統(tǒng)通信的速度,這種方式是值得的。所以新模型更加適合實現(xiàn)大規(guī)模的串口通信。
表2 模型的準(zhǔn)確率對比
主要原因是因為在通信元模型中,每個通信元都與唯一的下位機相綁定,保證了CPU通信時都能找到對應(yīng)的下位機。這樣,盡管下位機的數(shù)量多,但對于上位機而言,一個CPU每次只處理與一個下位機之間的通信,這樣就保證了數(shù)據(jù)通信的準(zhǔn)確率。另外,在傳統(tǒng)模型的串口通信中,如果串口數(shù)量過多,很容易造成數(shù)據(jù)傳輸超時。大量的數(shù)據(jù)堵塞在串口兩端,影響了整個系統(tǒng)的正常執(zhí)行。而通信元模型的超時率就很低,因為每個通信元中都綁定了超時處理方式,一旦發(fā)生串口數(shù)據(jù)堵塞時,程序?qū)⒘⒖虉?zhí)行通信元中的超時處理函數(shù),從而避免了數(shù)據(jù)堵塞現(xiàn)象。當(dāng)數(shù)據(jù)量巨大時,這種通信元超時處理的方式就更加明顯。
目前固定床間歇式造氣爐在我國中小型氮肥企業(yè)運用廣泛,其控制主要采用集散控制系統(tǒng)。而以PC機為基礎(chǔ)的集散控制系統(tǒng),上位機監(jiān)控軟件是實現(xiàn)其控制任務(wù)的核心。該文討論開發(fā)的造氣爐節(jié)能監(jiān)控組態(tài)軟件吸收了組態(tài)的思想,包含兩個部分,一個是組態(tài)部分,一個是運行部分。組態(tài)部分是一個應(yīng)用開發(fā)集成環(huán)境,用于建立監(jiān)控界面,配置相關(guān)參數(shù),并自動生成說明書供工程技術(shù)人員查閱。運行部分是一個實時運行環(huán)境,用來運行組態(tài)文件,監(jiān)控造氣爐工作。該軟件既吸收了組態(tài)軟件的精華——開發(fā)效率高、成熟穩(wěn)定、易于維護,又針對造氣爐這個特定行業(yè),功能純粹、成本低廉,適合中小型企業(yè)應(yīng)用實施,具有較高的工程意義和市場價值。
4 結(jié)論
IOCP思想既可以用于Socket套接字網(wǎng)絡(luò)通信,也可以用于多串口的網(wǎng)絡(luò)通信。基于IOCP思想設(shè)計的通訊元新模型是一種能
夠合理的利用和管理多線程的機制,該模型能夠有效管理多串口通信的線程,增強了程序的可移植性,提高了系統(tǒng)的工作效率。在為安徽某公司設(shè)計的工業(yè)造氣爐監(jiān)控組態(tài)軟件,采用了該基于IOCP核心思想的通訊元新模型,經(jīng)過壓力測試,實現(xiàn)了2000人同時在線的項目需求。實際運行表明該模型具有簡單的接口和穩(wěn)定、高效的運行機制。
參考文獻(xiàn):
[1] Richter J. Advanced Windows (3rd edition) [M]. USA: Microsoft Press,1997.
[2] Beveridge J, Wiener R. Multithreading Applications in Win32: The Complete Guide to Threads (Addison-Wesley Microsoft Technology Series) [M]. USA: Addson-Wesley Professional,1996.
[3] Jones A, Ohlund J. Network Programming for Microsoft Windows (2nd edition) [M]. USA: Microsoft Press, 2002.
[4] Jones A, Deshpande A. Windows Sockets 2.0: Write Scalable Winsock Apps Using Completion Ports [J]. MSDN Magazine, Microsoft Press, October 2000:30-35.
[5] Asche R. Writing Windows NT Server Applications in MFC Using I/O Completion Ports [J].MSDN Magazine, Microsoft Press, September 1996:25-30.
[6] Atanasova M, Cleeton L, Mike Flasko. Get Connected With The .Net Framework 3.5[J].MSDN Magazine, Microsoft Press, September 2007:42-49.
[7] Lee H, Park T. Design and Implementation of an Online 3D Game Engine [J]. Lecture Notes in Computer Science, Springer Berlin / Heidelberg, 2004:837-842.
[8] Kim G B. A method of generating massive virtual clients and model-based performance test [J]. Fifth International Conference on Quality Software, 2005:250-254.