• 
    

    
    

      99热精品在线国产_美女午夜性视频免费_国产精品国产高清国产av_av欧美777_自拍偷自拍亚洲精品老妇_亚洲熟女精品中文字幕_www日本黄色视频网_国产精品野战在线观看 ?

      μC/OS-II和LWIP的并發(fā)服務(wù)器與代理線程設(shè)計模式

      2014-06-25 02:46:20蔣俊鐘偉勝
      關(guān)鍵詞:句柄信號量網(wǎng)絡(luò)連接

      蔣俊,鐘偉勝

      (1.長沙 410081;2.江蘇省淮安技師學(xué)院)

      蔣俊(自由職業(yè)者),從事嵌入式開發(fā)6年,擅長μC/OS-II和LWIP,熟悉DSP和ARM開發(fā),自主開發(fā)過GUI庫,精通電能計量、測量、諧波分析;鐘偉勝(講師),主要研究方向為計算機網(wǎng)絡(luò)。

      引 言

      現(xiàn)有一嵌入式設(shè)備具備網(wǎng)絡(luò)通信功能,它要求設(shè)計成支持多臺數(shù)據(jù)采集器同時進(jìn)行通信,如圖1所示。多種原因(價格,功耗和尺寸)的限制導(dǎo)致該嵌入式設(shè)備的處理能力和存儲空間有限,因此選用μC/OS-II操作系統(tǒng)和LWIP協(xié)議棧。在通信過程中,數(shù)據(jù)采集器充當(dāng)客戶端,嵌入式設(shè)備是服務(wù)器,顯然,需要將該嵌入式設(shè)備設(shè)計成并發(fā)服務(wù)器,另外為節(jié)省內(nèi)存,需要設(shè)計代理線程模式。

      圖1 多臺采集器與嵌入式設(shè)備通信

      1 基于μC/OS-II動態(tài)生成線程

      一般來說OS都支持動態(tài)生成線程(或進(jìn)程),μC/OS-II也不例外,對于程序員來說,要處理4方面的問題:線程的正文、優(yōu)先級、堆??臻g和檢測堆棧占用率。

      正文(text)即線程的執(zhí)行代碼,經(jīng)常組織成一個無限循環(huán)的函數(shù),更具普遍規(guī)律的是,在網(wǎng)絡(luò)開發(fā)中多個線程的正文都是同一個函數(shù),因為這些線程基本上完成相同的任務(wù),差異只是連接的主機不同。

      μC/OS-II中的優(yōu)先級具有十分重要的意義,不僅影響該線程的調(diào)度,而且在整個系統(tǒng)中它是唯一的ID,可以分配一段ID號給動態(tài)線程。

      最重要的工作是堆棧的處理,當(dāng)生成一個線程時需要給它分配一段內(nèi)存充當(dāng)堆棧,當(dāng)刪除該線程時需要回收這段內(nèi)存。

      根據(jù)線程個數(shù)與每個線程堆棧大小定義一塊內(nèi)存區(qū),然后使用OS提供的OSMemCreate()生成動態(tài)內(nèi)存區(qū),每當(dāng)生成一個線程時,調(diào)用OSMemGet()來獲取一塊內(nèi)存,將該內(nèi)存的句柄保存;刪除一個線程時,調(diào)用OSMemPut()將該內(nèi)存回收。這里有一個問題,怎么查找被刪除線程的堆棧呢?其實它是根據(jù)該線程的優(yōu)先級號來完成的。

      一個線程可以調(diào)用OSTaskDel()來刪除自己,那么它可以回收自己的堆棧嗎?事實上,這樣做很危險!當(dāng)一個線程沒有完全刪除時,它是依賴堆棧來運行的,如果此時回收了堆??臻g,可能會帶來致命的錯誤。假設(shè)一個線程回收自己的堆棧且該內(nèi)存立即被別的線程使用,那么當(dāng)它還想使用這個堆棧執(zhí)行最后一些工作時,堆棧里的有效數(shù)據(jù)已經(jīng)被破壞了,這可能會帶來程序的崩潰,而且這種錯誤很難查找。

      一個安全可行的辦法是,一個線程向創(chuàng)建者發(fā)送消息——請回收我的堆??臻g,然后刪除自己,注意這2個動作必然是“原子的”,否則上述的錯誤就不可避免了。μC/OS-II在刪除線程的函數(shù) OSTaskDel()中提供鉤子函數(shù)App_TaskDelHook(),并且調(diào)用該鉤子函數(shù)時中斷被關(guān)閉,從而保證原子操作,可以在該函數(shù)中發(fā)送消息。

      最后,一個強大的嵌入式系統(tǒng)需要檢測線程的堆棧占用率,以防止堆棧溢出帶來的內(nèi)存錯誤。引入動態(tài)線程后,線程個數(shù)是未知的,該如何檢測堆棧占用率呢?這個工作可以交給OS來完成,因為它最了解哪些線程已經(jīng)被創(chuàng)建(通過查看OS_TCB來完成),可以簡單地調(diào)用OSTaskStkChk()遍歷所有優(yōu)先級號,對于已創(chuàng)建線程會返回堆棧使用數(shù)據(jù),不存在的線程會返回錯誤信息(如該線程不存在)。[1]

      2 基于LWIP的并發(fā)服務(wù)器

      我們先來解決一個理論問題:為什么網(wǎng)絡(luò)通信多連接需要設(shè)計并發(fā)線程,用一個線程來查詢并處理多連接是否可以呢?回答這個問題需要看看處理一個網(wǎng)絡(luò)連接的線程到底在干什么。在LWIP協(xié)議棧中,當(dāng)線程調(diào)用netconn_recv()等待連接主機的報文時會被阻塞在郵箱recvmbox上,直到接收成功該線程才進(jìn)行下一步處理。阻塞在OS中是通過切換CPU來實現(xiàn)的,阻塞時間內(nèi)該線程什么也干不了,查詢并處理多連接是不可能的。因此,一個線程處理一個網(wǎng)絡(luò)連接,這種模式最自然,也最科學(xué)。

      這里有一個主線程負(fù)責(zé)偵聽網(wǎng)絡(luò),每建立一個網(wǎng)絡(luò)連接時創(chuàng)建一個新線程并傳遞網(wǎng)絡(luò)連接句柄,新線程開始處理對應(yīng)網(wǎng)絡(luò)連接上的所有事務(wù),直到該網(wǎng)絡(luò)連接斷開時才刪除自己,并通知主線程回收堆??臻g,整個工作過程如圖2所示。

      圖2 多線程與并發(fā)連接

      結(jié)合LWIP看上述過程的實現(xiàn),主線程阻塞在netconn_accept()上,每接收一個新連接句柄struct netconn*p_stNetConn,就會創(chuàng)建一個新線程并傳遞該句柄。新線程將阻塞在netconn_recv()上,每接收一個網(wǎng)絡(luò)數(shù)據(jù)包struct netbuf*p_stNetBuf后進(jìn)行處理,新線程通過查詢ERR_IS_FATAL(p_stNetConn->err)來得知網(wǎng)絡(luò)連接是否有效,如果無效,則刪除自己并通知主線程回收堆??臻g。[3]

      3 代理線程設(shè)計模式

      從圖1中可以看出,無論多少個數(shù)據(jù)采集器,嵌入式設(shè)備的數(shù)據(jù)都是一致的,即數(shù)據(jù)與客戶端連接個數(shù)無關(guān);另外,每個數(shù)據(jù)采集器與設(shè)備通信的操作是相同的(一個優(yōu)秀架構(gòu)會保證通信操作的同構(gòu)性)。因此,引入代理線程設(shè)計模式,至少具備2方面的優(yōu)點:

      ①節(jié)省內(nèi)存。假設(shè)解析通信協(xié)議需要N字節(jié)內(nèi)存,如果新建M個線程,那么采用代理線程將節(jié)省N×(M-1)字節(jié)內(nèi)存,除代理線程外其他都不需要解析協(xié)議,這對于嵌入式系統(tǒng)寶貴內(nèi)存來說是一個極大的優(yōu)勢。

      ② 避免競態(tài)。一份數(shù)據(jù)如果被多個線程共享,那必定會帶來令人頭痛的競態(tài)問題,設(shè)計者不得不花費大量精力來保證線程安全;采用代理線程后,該數(shù)據(jù)只被一個線程操作,從源頭避免共享,降低設(shè)計復(fù)雜度。[2]

      圖3描述了代理線程的工作原理,當(dāng)客戶端Client_i向線程Thread_i發(fā)起通信請求時,線程把該請求委托給Proxy-Thread來完成,Proxy-Thread解析該委托任務(wù)并回應(yīng)客戶端Client_i。同時,也顯示了這種設(shè)計模式的缺點,需要線程之間通信和少量的時間開銷。

      圖3 代理線程通信原理

      在多線程設(shè)計中不得不提的是時序問題,它可以清晰地反映線程之間是如何交互的,OS是如何調(diào)度線程的以及系統(tǒng)的運行軌跡。在本設(shè)計中,委托線程與代理線程的交互如圖4所示,每當(dāng)委托線程提交任務(wù)后它就被阻塞,直到代理線程處理完該任務(wù)才解除阻塞;另外代理線程負(fù)荷最重,它占用大部分的CPU資源。

      圖4 線程交互時序圖

      委托線程與代理線程之間的通信接口該怎樣設(shè)計呢?從需求出發(fā),代理線程完成委托線程的任務(wù)需要以下資源:網(wǎng)絡(luò)連接句柄、接收數(shù)據(jù)包指針、同步信號量和委托線程私有數(shù)據(jù)存儲區(qū)。發(fā)送回應(yīng)數(shù)據(jù)包必須提供網(wǎng)絡(luò)連接句柄;要解析協(xié)議必須依賴接收數(shù)據(jù)包;當(dāng)代理線程完成任務(wù)后需要同步委托線程,這里將使用信號;客戶端往往需要設(shè)置委托線程,數(shù)據(jù)將保存在它的私有數(shù)據(jù)存儲區(qū)。數(shù)據(jù)結(jié)構(gòu)的設(shè)計如圖5所示。

      圖5 線程通信接口

      在上述通信接口設(shè)計中有SemProtect用于保護(hù)線程的私有數(shù)據(jù)單元,這個信號量有存在的必要嗎?以圖6中沒有設(shè)置信號保護(hù)的情況為例,這將直接導(dǎo)致一個錯誤:當(dāng)Proxy需要通過連接句柄主動發(fā)送數(shù)據(jù)時,委托線程搶奪了CPU,并將該連接句柄置為無效,等Proxy再次獲得CPU時,它并不知道該句柄已經(jīng)無效了,發(fā)送數(shù)據(jù)將會導(dǎo)致LWIP協(xié)議棧紊亂。

      圖6 沒有信號量保護(hù)導(dǎo)致錯誤

      解決這個問題的辦法就是原子操作,即檢測線程有效與使用連接句柄發(fā)送數(shù)據(jù)不能被打斷,信號量能夠勝任這種場合。圖7和圖8表明,無論Proxy先還是后,獲取信號量都能避免上述狀況下錯誤的發(fā)生。

      圖7 Proxy先獲取信號量

      圖8 Proxy后獲取信號量

      結(jié) 語

      本文重點研究了基于μC/OS-II和LWIP的嵌入式系統(tǒng)下并發(fā)服務(wù)器和代理線程的實現(xiàn)模式,它具備網(wǎng)絡(luò)多連接(數(shù)目僅依賴內(nèi)存大?。┖蜆O大節(jié)省內(nèi)存的優(yōu)勢,深入探究線程同步和網(wǎng)絡(luò)開發(fā)陷阱,對于嵌入式系統(tǒng)網(wǎng)絡(luò)開發(fā)具備實用價值。

      論文中涉及的技術(shù)方法已在嵌入式產(chǎn)品上驗證成功,該產(chǎn)品軟件基于μC/OS-II V2.86和 LWIP V1.3.2,硬件基于LPC1768處理器和以太網(wǎng)口,實踐證明論文中的方法穩(wěn)定、可行。

      [1]Jean J Labrosse.嵌入式實時操作系統(tǒng)μC/OS-II[M].邵貝貝,等譯.北京:北京航空航天大學(xué)出版社,2007.

      [2]David E.Simon嵌入式系統(tǒng)軟件教程[M].陳向群,等譯.北京:機械工業(yè)出版社,2005.

      [3]Adam Dunkels.Design and Implementation of the LWIP TCP/IP Stack.Swedish Institute of Computer Science,2001.

      猜你喜歡
      句柄信號量網(wǎng)絡(luò)連接
      基于STM32的mbedOS信號量調(diào)度機制剖析
      個性化設(shè)置 Win10 的網(wǎng)絡(luò)連接信息
      電腦報(2019年5期)2019-09-10 07:22:44
      運動想象的大尺度動態(tài)功能網(wǎng)絡(luò)連接
      Nucleus PLUS操作系統(tǒng)信號量機制的研究與測試
      高校圖書館持久標(biāo)識符應(yīng)用研究
      編譯程序語法分析句柄問題分析與探討
      MFC應(yīng)用程序多線程混合顯示界面方法研究
      中小型網(wǎng)絡(luò)組建技術(shù)
      μC/OS- -III對信號量的改進(jìn)
      Linux操作系統(tǒng)信號量機制的實時化改造
      丰宁| 延津县| 且末县| 抚远县| 周宁县| 渑池县| 鹿邑县| 冷水江市| 苍梧县| 芦山县| 方城县| 射阳县| 乌拉特后旗| 渝中区| 达州市| 柳州市| 日土县| 班戈县| 洛川县| 崇州市| 东辽县| 新疆| 朔州市| 和政县| 柳州市| 沙雅县| 道孚县| 南昌县| 苗栗县| 商都县| 英吉沙县| 宁明县| 镇远县| 广丰县| 裕民县| 手游| 防城港市| 鄂托克旗| 邓州市| 获嘉县| 民权县|