輪詢法在混合訊息通訊中的缺陷

來源:互聯網
上載者:User

訊息通訊過程可以採取輪詢或者中斷兩種方式,本文嘗試對輪詢法的一個缺陷做出分析。

 

一般輪詢法的架構:

 

 

bool have_msg = false;<br />msg_struct msg;<br />while(1)<br />{<br /> have_msg = poll_msg(&msg);<br /> if(have_msg)<br /> {<br /> switch(msg.type)<br /> {<br /> case MSG_TYPE1:<br /> // deal_with_msg_type_1();<br /> case MSG_TYPE2:<br /> // deal_with_msg_type_2();<br /> case MSG_TYPE3:<br /> // deal_with_msg_type_3();<br /> default:<br /> // unknown_msg_type_error();<br /> }<br />}

 

在一般小程式中採取該方法並沒有任何問題,但是,在一個複雜系統中擔負底層通訊任務的通訊庫如果設計成這種方式,則會為編程帶來很多困難。

 

在一個複雜系統中,多線程技術會被廣泛採用。顯然,上面的迴圈遇到某個訊息就處理某個訊息,屬於單線程的工作模式。如何使得上面的程式適合多執行緒呢?可以考慮使用號誌。我們將上面接收資料的線程成為接收線程,使用資料的線程為背景工作執行緒。首先背景工作執行緒在號誌上睡眠等待資料,接收線程收到資料後將資料掛入背景工作執行緒訊息佇列,然後喚醒背景工作執行緒。到目前為止,我們已經可以發現第一個問題
了:系統中需要維護若干號誌和若干訊息佇列。這些工作必須由通訊庫使用者來維護。隨著通訊庫的使用者量越來越大,使用者的維護開銷也會越來越大。

 

關於第一個問題,也許還可以苟且忍受。但是,接下來的第二個問題
會讓問題更加複雜。考慮這樣一種情境:type1和type2兩種訊息具有依賴關係,而某個功能的實現需要先接收到type1訊息,然後接收到type2訊息。我們可以讓實現次功能的背景工作執行緒依次等待兩個號誌即可。但是,如果系統中還存在第三個線程,它也需要使用type1訊息呢?此時單一的號誌已經不能解決問題了!當type1訊息到達時,type1訊息佇列上的號誌是喚醒原來的背景工作執行緒呢還是喚醒第三個線程?這個問題不解決,要麼會丟包,要麼會讓代碼內部邏輯混亂。那麼,有補救辦法嗎?有!在上面的訊息接收線程中進一步細分訊息類型,比如,將type1細分成type1_for_thread_work, type1_for_thread_third。此時,接收線程趨向於混雜。一旦系統中類似情況很多的時候,無論是效率還是代碼可維護性,都會受到極大挑戰。

 

解決上面問題的方法有2種:

1、互斥、阻塞地收發資料包

2、採用多連接埠,不同的while(1){}針對不同的連接埠。上層應用通過使用不同的連接埠來避免訊息混雜。

 

描述了單一連接埠發存在的問題,以及多連接埠的優勢。

 

 

 

 

 

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.