亚洲av成人无遮挡网站在线观看,少妇性bbb搡bbb爽爽爽,亚洲av日韩精品久久久久久,兔费看少妇性l交大片免费,无码少妇一区二区三区

Chinaunix

標題: 談?wù)勀憬佑|的通訊程序的模型 [打印本頁]

作者: duanjigang    時間: 2011-01-01 22:15
標題: 談?wù)勀憬佑|的通訊程序的模型
本帖最后由 duanjigang 于 2011-01-10 16:33 編輯

################2011-01-06
在1,2,4,5,67,22樓對目前涉及到的三種模型或者說程序的實現(xiàn)方法,做了詳盡的描述,歡迎大家積極拍磚,提出改進建議,或者發(fā)起實踐活動來實現(xiàn)這樣的設(shè)計思路,并與我們分享您的經(jīng)驗。

推薦下34樓的做法,個人感覺也很不錯
########################

應(yīng)用程序也做了不少了,特別是在通訊這塊做了好幾年,好幾個項目,來來回回,思想和選擇經(jīng)過了好幾番轉(zhuǎn)變,經(jīng)常會想起一些技術(shù)上的選擇問題,不知道該如何取舍,今晚屋子比較安靜,整理下思緒,發(fā)起這個話題,順便聽聽大家的看法。

   剛開始接觸網(wǎng)絡(luò)編程時,寫的最簡單的通訊程序,就是server-client一對一的模型,可能還不知道有非阻塞和select等概念,只是覺得測試數(shù)據(jù)發(fā)送過去了,接收到了就很高興,當面臨多連接,多種消息類型時,就開始頭大了。大概07年初的時候,我當時的想法,就跟前不久一個同學(xué)的設(shè)計思路一樣,對于一對多的通訊程序,服務(wù)器監(jiān)聽,接受到一個客戶端請求時,就為該連接創(chuàng)建一個線程,并且把獲取到的連接套接字交給線程去使用,當子線程完成通訊或者出錯后,就會關(guān)閉連接套接字,然后退出。這個模型在我當時看來很厲害了(應(yīng)該比同學(xué)問那個,給每個新獲取的連接套接字創(chuàng)建一個進程強點吧,呵呵),當時這個程序也是在客戶那里跑起來,基本上線了,但是印象里出了不少問題,多線程程序在我印象里更不好調(diào)試。。反正是被這個寫法折騰的夠苦,后來一提到多線程處理多連接,每個線程一個連接的做法,我就頭大。呵呵,不知道有沒有人這樣寫,談?wù)勛约呵擅畹脑O(shè)計或者遇到的問題?
第一種模型,是否可以用以下圖來表示?

作者: duanjigang    時間: 2011-01-01 22:29
本帖最后由 duanjigang 于 2011-01-02 10:43 編輯

呵呵,早上看看昨天的文字,發(fā)現(xiàn)用詞很土。:wink:
后來看到了第二種寫法,覺得不錯。

客戶端程序分為兩個線程:連接線程和數(shù)據(jù)處理線程。
在提出select和poll或者epoll之前,針對多個連接的通訊,大都使用的非阻塞socket吧。

     先說說連接線程,連接線程和數(shù)據(jù)線程共享一個server列表,或者叫一個server list.這個server列表的每一個節(jié)點,代表了
一個將要連接過去的主機,同時還存儲了該跟主機相關(guān)的信息,最常見的是IP地址,編號,socket描述符,發(fā)送緩沖區(qū),發(fā)送數(shù)據(jù)指針,數(shù)據(jù)總長度等信息。連接線程要做的事情很簡單,遍歷主機列表的每一個節(jié)點,如果發(fā)現(xiàn)某個主機的連接狀態(tài)處于“未連接”狀態(tài),則嘗試連接該主機,當然這個連接也是有超時限制的。如果連接成功,存儲該到該主機的連接的socket描述符,修改連接標志位。標明該主機已經(jīng)被連接上,其實也就是通知數(shù)據(jù)處理線程,該主機可以進行通訊了。
      再說數(shù)據(jù)處理線程,數(shù)據(jù)處理線程顧名思義,就是處理數(shù)據(jù)線程,從客戶端的角度來說,數(shù)據(jù)處理線程大多數(shù)情況下是做出發(fā)送數(shù)據(jù)的狀態(tài)。在這個模型中,也是如此,數(shù)據(jù)處理線程也遍歷主機列表,檢查每個主機的連接狀態(tài),如果該主機已經(jīng)連接上,并且發(fā)送緩沖區(qū)有數(shù)據(jù)未發(fā)送出去,則使用非阻塞的方式向該主機發(fā)送數(shù)據(jù),如果發(fā)送失敗,則關(guān)閉socket,并且修改主機的連接狀態(tài)為未連接狀態(tài),以告知連接線程,這個主機已經(jīng)斷開了,你丫需要重新去連接它了。如果發(fā)送成功,則更新發(fā)送緩緩沖區(qū)的數(shù)據(jù)指針,注意,這種發(fā)送沒必要在一個while循環(huán)中一直發(fā)送,直到發(fā)送完成,個人覺得發(fā)送一次就可以了,不過好像也有人嘗試發(fā)送最多三次。個人理解,為了減少在一臺主機上的長時間發(fā)送而造成對其它主機數(shù)據(jù)發(fā)送的延遲影響,還是只發(fā)送一次好。
第二種方式的客戶端程序可以用這個圖來描述下。

作者: yangsf5    時間: 2011-01-02 01:25
圖是紅叉叉。。
沒必要1個連接一個線程把。
作者: duanjigang    時間: 2011-01-02 09:01
圖是紅叉叉。。
沒必要1個連接一個線程把。
yangsf5 發(fā)表于 2011-01-02 01:25



    嗯,是的,呵呵,最初是這么設(shè)計的,而且現(xiàn)在有些剛接觸網(wǎng)絡(luò)通訊類程序的人也會下意識的去這么考慮。
我是想從一開始到現(xiàn)在,把所有遇到過的寫法大致上都總結(jié)下,大家一起討論每種的問題,優(yōu)缺點和性能比較。
作者: duanjigang    時間: 2011-01-02 11:03
本帖最后由 duanjigang 于 2011-01-02 11:06 編輯

接著來說第二種模型的服務(wù)端程序,對于服務(wù)端程序來說,跟客戶端程序類似,也是兩個線程工作。
      一個連接接收線程,一般來說,都是主線程來負責,創(chuàng)建socket后,bind,listen。。然后在一個死循環(huán)當中嘗試accept來自不同主機的連接請求。每收到一個連接請求,就把該連接的IP地址,端口等信息存儲到連接列表當中,并且初始化接收緩沖區(qū)等信息。
    另外一個是數(shù)據(jù)接收線程,該線程遍歷連接列表,嘗試從每一個連接讀取數(shù)據(jù),如果讀取失敗,則關(guān)閉連接套接字,釋放該連接節(jié)點。如果接收成功,則檢測是否是一個完整的消息,是的話,則進行處理,不是一個完整的消息,則繼續(xù)緩存,更新接收緩沖區(qū)的指針。
  服務(wù)器端程序相對客戶端程序來說,處理的事務(wù)少點。
服務(wù)端程序的結(jié)構(gòu)和工作流程可以用下圖來表示下:

作者: duanjigang    時間: 2011-01-02 11:39
第二種雙線程的方式已經(jīng)是一種不錯的模型了,在實際中應(yīng)用也不少,上面量段文字和圖片說明了服務(wù)端和客戶端的基本工作方式和數(shù)據(jù)結(jié)構(gòu)梗概。不過有些細節(jié)還是需要注意并加以處理的:
  我們都知道,服務(wù)端和客戶端都是采用非阻塞方式進行數(shù)據(jù)的發(fā)送和接收的。這樣就有一個特點:對于專注從事于數(shù)據(jù)發(fā)送的客戶端程序來說,如果客戶端到服務(wù)端的網(wǎng)絡(luò)出現(xiàn)中斷,客戶端的發(fā)送操作會出錯,這時,客戶端程序能夠發(fā)現(xiàn)這個故障,并且能夠進行正確的處理(關(guān)閉socket,后面嘗試重新連接)。而對于服務(wù)器端程序來說,因為它遍歷連接列表進行數(shù)據(jù)接收,采用的是非阻塞方式,即使客戶端的連接已經(jīng)斷開,他調(diào)用recv操作,返回的結(jié)果跟沒有收到數(shù)據(jù)是一樣的,都是0(這個結(jié)論我應(yīng)該沒有記錯吧,如果有錯,望指出)。也就是說,服務(wù)端通過只讀取的操作是無法發(fā)現(xiàn)客戶端的斷開狀態(tài)的。從系統(tǒng)資源角度考慮,會造成很多未完全關(guān)閉的連接,另外,從服務(wù)端程序來考慮,也是無法忍受的,比如服務(wù)端采用的連接列表長度為1000,如果有幾十個客戶端斷開連接并且重新連接幾次,這樣在服務(wù)端的連接列表里會增加上百個貌似正常實際上卻是無效的連接節(jié)點,時間再長點,就會導(dǎo)致服務(wù)端列表的溢出,另外,從后面的話題的角度出發(fā),列表過長,會導(dǎo)致接收線程遍歷的節(jié)點次數(shù)增大,浪費過多的CPU時間。
作者: duanjigang    時間: 2011-01-02 11:56
本帖最后由 duanjigang 于 2011-01-02 19:10 編輯

接著6樓的問題。
  既然只讀取的操作不能發(fā)現(xiàn)連接的斷開,為什么不增加一個發(fā)送操作?是的,這個想法很好,不過我們要明白,這個發(fā)送操作的目的只是為了檢測客戶端連接的狀態(tài)。
  既然服務(wù)端會通過發(fā)送數(shù)據(jù)的方法來檢測客戶端的在線狀態(tài),那么客戶端就不能置之不理,禮尚往來還是有必要的,因為如果客戶端不理會服務(wù)端的發(fā)送數(shù)據(jù)的話,服務(wù)端發(fā)送到客戶端接收緩沖區(qū)的數(shù)據(jù)就不會被讀取,如果不存在超時丟棄或者覆蓋的話,接收緩沖區(qū)總會被寫滿的。因此,客戶端還是需要去讀取服務(wù)端發(fā)送過來的檢驗數(shù)據(jù)的。
   跟據(jù)上面的情形,可以增加這樣一項工作,在服務(wù)器端的主機列表的每個節(jié)點上存儲接收到客戶端數(shù)據(jù)的最新時間,然后定義一個超時時間,如果超過這個時限沒有收到來自某個主機的數(shù)據(jù),則嘗試向該主機發(fā)送一個握手消息,這時就能檢測是否連接已經(jīng)斷開了。
   對于客戶端而言,為每一個服務(wù)器保存一個發(fā)送數(shù)據(jù)的最新時間,如果最后一次發(fā)送數(shù)據(jù)的時間到目前的時間差超過這個時限,則嘗試從服務(wù)端讀取握手消息,這樣就能把服務(wù)器端發(fā)過來的握手消息接收過來,比較理想的解決了上面討論中可能出現(xiàn)的問題。
     這種非阻塞的模型,有些人認為是比較浪費CPU時間的,不過通過一些方法可以適當降低CPU使用的,在連接列表不是特別長,并且每個連接都不是特別空閑的情況下,性能還是很不錯的。
后面有時間,我把這種模型的實現(xiàn)整理下,放出來大家可以參考下。
作者: Godbach    時間: 2011-01-02 17:58
duan 兄好文章,受益匪淺。
作者: duanjigang    時間: 2011-01-02 18:59
duan 兄好文章,受益匪淺。
Godbach 發(fā)表于 2011-01-02 17:58



    呵呵,只是想把自己遇到的各種情形列舉下,希望大家能夠討論每種模型的應(yīng)用范疇和優(yōu)缺點。今天還沒寫完,明天接著總結(jié):wink:
老趙多多提點意見啊
作者: duanjigang    時間: 2011-01-02 19:12
到目前為止,提到了兩種模型,歡迎大家積極拍磚討論喔。
關(guān)于select 和epoll等模型,歡迎熟悉的朋友積極發(fā)表感受。我明天寫寫基于ICE的模型(也是我目前正在使用的方式)。:wink:
作者: gvim    時間: 2011-01-02 20:03
本帖最后由 gvim 于 2011-01-02 20:29 編輯

我覺得多進程也是一個可以考慮的設(shè)計方向,很多時候,比多線程優(yōu)勢更大。線程的優(yōu)勢在于調(diào)度和資源量,問題在大量多線程系統(tǒng)本身的復(fù)雜和調(diào)試的困難。
兩個實例:1 是postgresql的服務(wù)模型,進程+shared mem。共享內(nèi)存只處理全局狀態(tài),每一個進程自我處理資源,現(xiàn)在大部分OS的任務(wù)切換性能不在是瓶頸。代碼很清晰,性能也很高,網(wǎng)上有個圖,可以看看。 不好的一點是內(nèi)存消耗量稍大。如果需要控制進程數(shù)量,一般前面有連接池。
2 是基于actor模型的通訊方式,如erlang,(雖然此進程非彼進程,但是實質(zhì)是一樣的"進程”)眾所周知的是它的擴展性和分布特性。
另外,每進程的耦合較低,如果不需要處理事務(wù)的話,我更傾向于進程,這樣可以在適當?shù)臅r候輕松的把計算分布到其它物理資源上處理(比如erlang)。

我做的關(guān)乎server的設(shè)計幾乎是這個模式的。
作者: gvim    時間: 2011-01-02 20:23
回復(fù) 10# duanjigang


個人覺得既然是討論模型的話,還是需要界定模型適用的領(lǐng)域,模型的解決方案,模型解決的問題,模型具有那些好的非功能性特性,模型的缺點,和其它模型的比較等等。
就像<design pattern>討論的那樣。
作者: duanjigang    時間: 2011-01-02 20:51
我覺得多進程也是一個可以考慮的設(shè)計方向,很多時候,比多線程優(yōu)勢更大。線程的優(yōu)勢在于調(diào)度和資源量,問題 ...
gvim 發(fā)表于 2011-01-02 20:03



    能說說多進程的任務(wù)是怎么劃分的嗎?呵呵,數(shù)據(jù)通訊,還有處理怎么劃分的。
作者: duanjigang    時間: 2011-01-02 20:53
回復(fù)  duanjigang


個人覺得既然是討論模型的話,還是需要界定模型適用的領(lǐng)域,模型的解決方案,模型解 ...
gvim 發(fā)表于 2011-01-02 20:23



    嗯,對的,我想從具體的引用談起,可能更容易討論起來,而后再把這些模型或者說程序的寫法就行比較和總結(jié)
作者: gvim    時間: 2011-01-02 22:16
回復(fù) 13# duanjigang


回歸到你給出的第一種圖,不過線程換成進程。
我過去傾向于用線程,但是嘗試很多之后設(shè)計和調(diào)試都隨著狀態(tài)或功能越復(fù)雜而越復(fù)雜,再加上我個人目標領(lǐng)域的關(guān)鍵約束不在內(nèi)存上,并且感謝現(xiàn)代操作系統(tǒng),進程和線程切換的代價已經(jīng)十分靠近,所以慢慢回歸到最簡單的方式,現(xiàn)在看來真是越簡單越美。直到了解了erlang的處理模式之后,更加深了這個認識。
作者: leiing    時間: 2011-01-03 00:21
樓主都是用長連接嗎?
長連接和短連接應(yīng)該怎么選?如網(wǎng)游服務(wù)器,IM服務(wù)器?
作者: duanjigang    時間: 2011-01-03 10:22
回復(fù)  duanjigang


回歸到你給出的第一種圖,不過線程換成進程。
我過去傾向于用線程,但是嘗試很多之 ...
gvim 發(fā)表于 2011-01-02 22:16



    呵呵,請教一個問題,多線程,多進程,相當于單線程有什么優(yōu)勢?通訊性能更高?還是程序的處理邏輯更簡單?givm熊能否說點詳細的感受。謝謝
如果用單線程的話,都不需要進程的切換。
作者: duanjigang    時間: 2011-01-03 10:26
樓主都是用長連接嗎?
長連接和短連接應(yīng)該怎么選?如網(wǎng)游服務(wù)器,IM服務(wù)器?
leiing 發(fā)表于 2011-01-03 00:21



    慚愧,一提到長連接和短連接,我都有些含糊,不知道你說得是不是開發(fā)人員主動控制的連接方式。
比如長連接就是連接上目標主機后一直不斷開?短連接就是通訊完成后關(guān)閉連接,下次事務(wù)再次連接?
如果是這樣的話,我一般的選擇就是,如果通訊很頻繁,而且1對N的N不是特別大的話,就長連接,如果通訊周期很長,比如5分鐘傳輸一次數(shù)據(jù),搞成短連接最好吧。
這是個人的一點看法,不知對否?
我們目前接觸到的情況是1對8的連接到1對300的連接,都用的恒久連接。因為幾乎每分鐘內(nèi)都有數(shù)據(jù)傳輸。
作者: dreamice    時間: 2011-01-03 13:31
到目前為止,提到了兩種模型,歡迎大家積極拍磚討論喔。
關(guān)于select 和epoll等模型,歡迎熟悉的朋友積極發(fā) ...
duanjigang 發(fā)表于 2011-01-02 19:12



    有空了只要沒人搶先的話我總結(jié),呵呵
研究了有一段時日了:wink:
作者: duanjigang    時間: 2011-01-03 16:16
有空了只要沒人搶先的話我總結(jié),呵呵
研究了有一段時日了
dreamice 發(fā)表于 2011-01-03 13:31



    老江趕緊整啊,我最近讀別人的代碼,select寫的,還不錯。epoll這塊還沒多少經(jīng)驗,新版開張,你要多多支持喔。
等咱把這些可能的模型都列出來,總結(jié)完了,再發(fā)起個實踐活動,做下性能和易用性的測試。久而久之,就能形成一些穩(wěn)定的模型供人試用了
作者: havey    時間: 2011-01-05 18:08
說的很好,一個很實用的話題,謝謝這些無私的朋友!
作者: duanjigang    時間: 2011-01-06 09:34
本帖最后由 duanjigang 于 2011-01-06 09:50 編輯

呵呵,感冒耽擱了幾天,今天把使用ICE中間件的這種方式補充上來:wink:

第三種方式,結(jié)合ICE中間件進行設(shè)計。
ICE提供了一個多系統(tǒng),多語言互通的中間件,通過使用slice語言定義一個.ice文件來實現(xiàn)不同程序的通訊數(shù)據(jù)結(jié)構(gòu)和調(diào)用方法的定義。
然后調(diào)用slice2XX(xx=cpp,java,php..)來生成對語言的代碼。對于開發(fā)人員來說,只需要把生成的java或者cpp代碼包含到自己的工程中來,客戶端填寫數(shù)據(jù)到對象中,調(diào)用定義的函數(shù)就行,服務(wù)端繼承接口中定義的虛函數(shù),實現(xiàn)數(shù)據(jù)處理即可。調(diào)用也十分簡單,從感性上理解,客戶端調(diào)用數(shù)據(jù)處理方法,服務(wù)端的方法就被調(diào)用了,它是一個類似于RPC的機制。
    有了ICE這個強有力的助手,數(shù)據(jù)發(fā)送和接收變得異常容易了,然后我們需要處理的就是連接的維護。
    服務(wù)器端不需要維護連接,因為對他來說,服務(wù)端就是一個類似回調(diào)函數(shù)的機制,它并不關(guān)心或者不清楚在某一個時刻,自己會被哪個遠程主機調(diào)用?蛻舳诵枰S護連接,因此,類似于模型2中的方法,在客戶端獨立一個線程,一直嘗試連接未連接上的主機即可。
    講講這種模型下我的一般設(shè)計方法:
     主線程啟動后創(chuàng)建兩個線程,一個客戶端線程,一個服務(wù)端線程,服務(wù)端線程運行后,就會處于阻塞狀態(tài),一直等待消息的到來,客戶端在運行后則會一直嘗試去發(fā)送數(shù)據(jù),而主線程下來要做的事情就是:遍歷它跟客戶端線程共享的那個主機列表,嘗試連接每一個沒有連接上的主機。
    這就是第三種模型,希望有改進意見的朋友積極發(fā)表看法和意見,謝謝!
作者: duanjigang    時間: 2011-01-06 09:52
第三種模型的一個好處就是,由于ICE使得客戶端和服務(wù)端的代碼變得簡單起來,我們可以很輕松的把客戶端的功能和服務(wù)端的功能用一個程序中的兩個線程來實現(xiàn)。這相對于1和2的模型來說,方便多了。
作者: myxxn    時間: 2011-01-06 16:33
而對于服務(wù)器端程序來說,因為它遍歷連接列表進行數(shù)據(jù)接收,采用的是非阻塞方式,即使客戶端的連接已經(jīng)斷開,他調(diào)用recv操作,返回的結(jié)果跟沒有收到數(shù)據(jù)是一樣的,都是0(這個結(jié)論我應(yīng)該沒有記錯吧,如果有錯,望指出)


如果是非阻塞,正常情況下如果沒有數(shù)據(jù),recv函數(shù)會返回-1,并且將錯誤代碼置為EAGAIN,如果recv返回0,其實代表的是遠端socket被關(guān)閉了

我也對服務(wù)器程序設(shè)計感興趣,大家多交流。
作者: duanjigang    時間: 2011-01-06 16:55
如果是非阻塞,正常情況下如果沒有數(shù)據(jù),recv函數(shù)會返回-1,并且將錯誤代碼置為EAGAIN,如果recv返回0, ...
myxxn 發(fā)表于 2011-01-06 16:33



    嗯,謝謝糾正,我晚上查下代碼,看看這塊具體處理流程!
作者: wucailiuxing    時間: 2011-01-07 10:55
這個話題開的太好了,我對這個話題也非常感興趣。
一般我常用的就是第二種方式,專門開一個監(jiān)聽線程來處理連接,對已經(jīng)連接好的分到空閑的工作線程中處理,在實際的過程中,我也遇到了客戶端不正常斷開,造成資源浪費的情況,我采取的方式是再開一個監(jiān)控線程,來掃描判斷每個連接的狀態(tài)。
作者: duanjigang    時間: 2011-01-07 11:01
如果是非阻塞,正常情況下如果沒有數(shù)據(jù),recv函數(shù)會返回-1,并且將錯誤代碼置為EAGAIN,如果recv返回0, ...
myxxn 發(fā)表于 2011-01-06 16:33



    呵呵,對您的說法我再次做了驗證。
對于阻塞和非阻塞的socket,如果server端一直保持recv的操作,對于發(fā)送端的異常退出,close并且正常退出,或者沒有數(shù)據(jù),server端通過recv是不能檢測到的,當返回值<0時,errno都是EAGIN,因此能不能這么說,純粹的recv工作的socket是不能檢測對端的退出的?
如果這樣的話,還是需要在沒有收到數(shù)據(jù)一段時間后通過發(fā)送心跳包來檢測連接的狀態(tài)的。:wink:
不知道我的說法有無紕漏?或者您再做做實驗,指出我可能存在的問題,謝謝!
作者: duanjigang    時間: 2011-01-07 14:34
本帖最后由 duanjigang 于 2011-01-07 14:35 編輯

把myxnn給我的消息貼下,相信他應(yīng)該不會介意吧,也是為了跟大家分享,呵呵:
你好,那個recv的問題我又做了一個實驗,
在阻塞模式下,client自動關(guān)閉時,server端的recv收到的卻是是0
非阻塞模式下我沒來得及重新做,但是我之前是用epoll做的,當client關(guān)閉連接時  我會收到一個可讀事件,這個時候再去讀的話,也是收到的0
您的郵箱可以告訴我一下嗎? 我把我的測試代碼發(fā)你看看有沒有問題
我的測試環(huán)境:
操做系統(tǒng):Ubuntu 8.04.3 (Linux 2.6.24-24-generic x86_64 )
g++:g++ (GCC) 4.2.4 (Ubuntu 4.2.4-1ubuntu4)

作者: duanjigang    時間: 2011-01-07 14:38
呵呵,應(yīng)該跟操作系統(tǒng)關(guān)系不大吧。recv本身的操作就是從本地緩沖區(qū)中讀取數(shù)據(jù),應(yīng)該跟發(fā)送端關(guān)系不大。
因此,對端狀態(tài)的探測還是需要心跳包的。
作者: myxxn    時間: 2011-01-07 15:33
本帖最后由 myxxn 于 2011-01-07 15:38 編輯

回復(fù) 29# duanjigang

恩,心跳協(xié)議肯定是必不可少的
不過我想心跳協(xié)議重點不在于檢查連接是否端掉,連接是否中斷從系統(tǒng)里面是肯定可以探測到的,
關(guān)鍵心跳協(xié)議能檢測到“被遠程調(diào)用端”是否“死”掉,比如說請求一個遠端的服務(wù),連接雖然沒斷,
但是服務(wù)器已經(jīng)死循環(huán)了,這個時候通過心跳協(xié)議的超時機制來檢測,這時就應(yīng)該主動把連接斷掉,然后重新請求一個可用的服務(wù)
作者: ashlv    時間: 2011-01-08 12:10
我覺得ESB是我見過的算是比較好的通訊模型了
作者: duanjigang    時間: 2011-01-08 12:19
本帖最后由 duanjigang 于 2011-01-08 12:22 編輯
我覺得ESB是我見過的算是比較好的通訊模型了
ashlv 發(fā)表于 2011-01-08 12:10



哈哈,另外一篇文章就在說ESB。。我還是孤陋寡聞了
作者: maclaurin    時間: 2011-01-09 23:05
我常用的通訊模型:
多reactor,用round_robin處理reactor的負載均衡,reactor與TCP連接為一對多的關(guān)系。
發(fā)送的數(shù)據(jù)使用消息隊列,單獨線程發(fā)送,處理超時重發(fā)以及EWOULDBLOCK重發(fā)問題。
心跳協(xié)議必須的,定時器可以集成到reactor里。
服務(wù)器間通訊現(xiàn)在直接用protocol buffer了,方便。
作者: jiang1013nan    時間: 2011-01-09 23:45


這個是我在最近打算換工作,總結(jié)以前項目的時候隨便畫的。

服務(wù)器主要分為兩個層次:通訊層和業(yè)務(wù)處理層。(采用epoll網(wǎng)絡(luò)模型)

在通訊層又分為兩個層次:
1)與客戶端的數(shù)據(jù)交互
      該模塊只負責接受請求、接受數(shù)據(jù)、發(fā)送數(shù)據(jù)(各為一個獨立的線程),接收到客戶端的數(shù)據(jù)之后將數(shù)據(jù)放入到數(shù)據(jù)隊列中,發(fā)送數(shù)據(jù)的時候從數(shù)據(jù)發(fā)送隊列中讀取數(shù)據(jù)進行發(fā)送;
2)與業(yè)務(wù)層的數(shù)據(jù)交互
      該模塊負責將從客戶端讀取的數(shù)據(jù)發(fā)送給業(yè)務(wù)處理進程和從業(yè)務(wù)處理進程讀取數(shù)據(jù),與業(yè)務(wù)處理進程通信采用的方式為:用fifo實現(xiàn)事件通知機制,用共享內(nèi)存實現(xiàn)queue達到數(shù)據(jù)傳輸?shù)哪康?br />
業(yè)務(wù)處理層比較簡單,用select接收到事件通知后,讀取數(shù)據(jù),處理數(shù)據(jù),再講處理結(jié)果放到數(shù)據(jù)隊列中,然后在用fifo來通知通訊層去讀取數(shù)據(jù),處理模型為reactor模型;

通訊層與業(yè)務(wù)處理層的數(shù)據(jù)是輪訓(xùn)方式nconnect++/業(yè)務(wù)處理層進程數(shù)。
作者: qiangtoucao121    時間: 2011-01-10 10:27
樓上的不錯
作者: duanjigang    時間: 2011-01-10 16:21
這個是我在最近打算換工作,總結(jié)以前項目的時候隨便畫的。

服務(wù)器主要分為兩個層次:通訊層和業(yè)務(wù)處 ...
jiang1013nan 發(fā)表于 2011-01-09 23:45



    jiang103nan兄弟這個模型不錯,我最近看了epoll后也是想把以前的模型改成你描述這樣的。
對了,性能測試有做過嗎?性能如何,并發(fā)如何?
作者: duanjigang    時間: 2011-01-10 16:24
我常用的通訊模型:
多reactor,用round_robin處理reactor的負載均衡,reactor與TCP連接為一對多的關(guān)系。
...
maclaurin 發(fā)表于 2011-01-09 23:05



    嗯,聽說protocol buffer是很不錯的一個咚咚,有空研究下。兄弟有空關(guān)于您使用的模型能詳細說點不?
到數(shù)據(jù)結(jié)構(gòu),算法層面。呵呵
作者: duanjigang    時間: 2011-01-10 16:32
同請教33樓和34樓兩個問題:
第一:你們的通訊程序獨立于應(yīng)用程序嗎???
也就是說把通訊做成純粹的通訊程序,要增加應(yīng)用業(yè)務(wù),對通訊而言只需要修改配置文件或者根本什么都不需要做?

第二:通訊程序發(fā)送的數(shù)據(jù)是分包的嗎?對于大數(shù)據(jù)量發(fā)送怎么做的?比如A應(yīng)用通過我們的通訊程序想發(fā)送一個文件到B應(yīng)用,怎么做的?
謝謝!
作者: jiang1013nan    時間: 2011-01-10 20:51
回復(fù) 36# duanjigang

在實際生產(chǎn)環(huán)境中達到了8K人左右額。
作者: maclaurin    時間: 2011-01-10 22:00
同請教33樓和34樓兩個問題:
第一:你們的通訊程序獨立于應(yīng)用程序嗎???
也就是說把通訊做成純粹的通訊 ...
duanjigang 發(fā)表于 2011-01-10 16:32



第一:你們的通訊程序獨立于應(yīng)用程序嗎???
獨立,一個前置通訊網(wǎng)關(guān)對應(yīng)多個應(yīng)用服務(wù)器。

第二:通訊程序發(fā)送的數(shù)據(jù)是分包的嗎?對于大數(shù)據(jù)量發(fā)送怎么做的?比如A應(yīng)用通過我們的通訊程序想發(fā)送一個文件到B應(yīng)用,怎么做的?
應(yīng)用層分包?如果是TCP,應(yīng)用層不管分包的事,如果是UDP的話,就要考慮分包,要用到應(yīng)用層協(xié)議里的frame_seq來維護包和包之間的上下文關(guān)系。發(fā)送文件,linux下用sendfile,windows下TransmitFile。

關(guān)于通訊模型,最近一直想用epoll_reactor來模擬proactor,boost::asio是實現(xiàn)了,可惜C用不上。
作者: jiang1013nan    時間: 2011-01-10 22:59
回復(fù) 40# maclaurin


    是的。對于處理UDP,目前我們沒有好的處理方案對于通訊與業(yè)務(wù)分離的架構(gòu)。在實際生產(chǎn)環(huán)境中,我們采用的是TCP的方式。
作者: 一介村夫    時間: 2011-01-10 23:21
本帖最后由 一介村夫 于 2011-01-10 23:24 編輯

多線程模型就像人彈,有人要死,卻拉上一大堆墊背的。

我再說一遍:多進程模型是用于每個進程干自己的事,互相不影響;多線程模型是用于所有線程協(xié)調(diào)干一件事,每個線程負責一個部分。

多線程模型中的線程,彼此的工作內(nèi)容應(yīng)該是不同的,同時又是互補的,大家完成的是同一件事的不同部分。基于這樣的理解進行設(shè)計,就不存在“人彈”的可能性。

所以在一般通訊服務(wù)程序的場合,絕對應(yīng)該使用多進程模型。

進程與線程,看著相似,實際的出發(fā)點和作用是不同的,所以不能亂用,要根據(jù)應(yīng)用模型進行選擇。再說得淺顯點就是:在一個多線程模型中,任何兩個線程都不應(yīng)該使用同一個函數(shù)作為入口點!
作者: jiang1013nan    時間: 2011-01-11 09:05
回復(fù) 42# 一介村夫


嗯。有一定道理嗯。
但是也存在多個線程干一類事情,但是相互獨立的事情。
作者: duanjigang    時間: 2011-01-11 09:53
第一:你們的通訊程序獨立于應(yīng)用程序嗎???
獨立,一個前置通訊網(wǎng)關(guān)對應(yīng)多個應(yīng)用服務(wù)器。

第二 ...
maclaurin 發(fā)表于 2011-01-10 22:00



    恩,大致明白了。有個問題喔,通訊程序相當于做成了一個獨立的中間件了。這樣的話,應(yīng)用程序其實不必再關(guān)注通訊程序使用到的協(xié)議了吧?
如果你們的通訊已經(jīng)獨立于應(yīng)用了,我想應(yīng)該是這樣吧?那么,這時是不是都應(yīng)該用TCP來實現(xiàn)?為了可靠起見。謝謝
作者: 一介村夫    時間: 2011-01-11 10:00
回復(fù)  一介村夫


嗯。有一定道理嗯。
但是也存在多個線程干一類事情,但是相互獨立的事情。
jiang1013nan 發(fā)表于 2011-01-11 09:05



    一個進程崩潰,毀掉的是一大批事情,而不僅僅是出問題的那一個,這不合理。
而且在這種模型中,你無法中斷一個已經(jīng)出現(xiàn)問題的獨立事情。

進程和線程在系統(tǒng)開銷上的那點差別,遠遠小于你應(yīng)用程序?qū)懙煤门c不好的差別,不同的人為同一個事情寫程序,開銷差別都很大,何必在乎進程和線程開銷間的這一點差別呢?真在乎系統(tǒng)開銷,就先認真寫好自己的應(yīng)用程序吧。

所以,一定要選擇適合的模型做適合的事情。
作者: duanjigang    時間: 2011-01-11 10:17
多線程模型就像人彈,有人要死,卻拉上一大堆墊背的。

我再說一遍:多進程模型是用于每個進程干自己的事 ...
一介村夫 發(fā)表于 2011-01-10 23:21



    阿村說的很精辟,應(yīng)該是多年的經(jīng)驗感言!
但是有些人出于節(jié)省代碼量的想法還是違背這些原則了,比如為了使用公共的全局變量,節(jié)省代碼量,把通訊的server端和client端做成了兩個線程。
呵呵,我就這么搞過
關(guān)于數(shù)據(jù)處理部分,現(xiàn)在完全做成了獨立的進程,每個消息處理插件一個子進程,也是充分考慮到“人彈”這個因素了。
看樣子通訊程序本身,還應(yīng)該再分離出來。這樣才合理。
作者: duanjigang    時間: 2011-01-11 10:23
當然:連接和數(shù)據(jù)發(fā)送在一個進程中用多線程,這是合理的。
但是連接和數(shù)據(jù)發(fā)送線程所屬的進程和數(shù)據(jù)接收部分,應(yīng)該獨立開,是兩個進程
作者: swxlion    時間: 2011-01-11 12:02
回復(fù)  duanjigang

在實際生產(chǎn)環(huán)境中達到了8K人左右額。
jiang1013nan 發(fā)表于 2011-01-10 20:51



    關(guān)于這個數(shù)據(jù),是在怎么樣的情況下獲得的?
不知單臺服務(wù)器是怎樣的配置情況:操作系統(tǒng)、CPU位數(shù)、CPU個數(shù)x單個CPU核數(shù)、內(nèi)存大小,網(wǎng)卡/網(wǎng)絡(luò)帶寬限制、非業(yè)務(wù)相關(guān)壓力負載情況(比如在同一臺機器上,是否有web服務(wù)器正在提供非被測業(yè)務(wù)的服務(wù)?)。每秒發(fā)包數(shù)、平均包大小。因為在我以前的性能測試經(jīng)驗中,這些對最終性能數(shù)據(jù)影響很大。如果沒有全部說明的話,則對比性就不強了。
作者: qianhulou    時間: 2011-01-11 12:42
我一直都用的阻塞, 但是對于非阻塞 我個人認為和阻塞差不多.  對端主動關(guān)閉, RECV返回0, 對端異常關(guān)閉 非close() shutdown的 RECV返回-1, 如果沒有數(shù)據(jù)來 RECV也返回-1, 根據(jù)errno來區(qū)分是哪中情況. 心跳包 是用來檢測路由的, 比如A->switch->B , switch那里網(wǎng)線掉了, A和 B一般情況是檢測不到的, 除非那個交換機有這個功能或者SOCKET設(shè)置了那個TCP自測的選項.如果A->B直連的話, 只要網(wǎng)線中間不斷開, 有沒有心跳包 效果一樣....
作者: ruifengzhangyi    時間: 2011-01-11 14:48
有個問題想請教ls各位大拿
采用第一種模型
while(1)
{
accept()
pthread_create()
}
是否存在一些弊端,對于高并發(fā)的請求的情況下,服務(wù)器容易當?shù)簦荒懿扇]有辦法的辦法在pthread_create()
后睡眠幾微秒,可以一定程度的緩解。
作者: jiang1013nan    時間: 2011-01-11 15:14
回復(fù) 45# 一介村夫


   嗯。沒錯。關(guān)鍵是合適的場景選擇合適的模型,其中一個線程出現(xiàn)問題,一個進程都會崩潰。多個進程則不會出現(xiàn)同樣的問題,apache就是多個子進程干同樣的事情。
作者: jiang1013nan    時間: 2011-01-11 15:19
回復(fù) 47# duanjigang


如果將讀和寫分別放在不同的進程中,就意味著server和client至少保持一個連接,代價是不是太高啦?如果將讀和寫分別放在不同的線程中,只需要保持一個連接。
作者: jiang1013nan    時間: 2011-01-11 15:21
回復(fù) 44# duanjigang


  是的,沒錯。

通訊層就是類似于數(shù)據(jù)中間件,負責client與業(yè)務(wù)處理層面的數(shù)據(jù)接受與發(fā)現(xiàn)。如果涉及到udp的話,采用這種方式似乎有些困難額。
作者: jiang1013nan    時間: 2011-01-11 15:23
回復(fù) 46# duanjigang


    我認同將通訊和業(yè)務(wù)進行分離,通訊只負責數(shù)據(jù)的接受;業(yè)務(wù)負責處理數(shù)據(jù),很大情況下,業(yè)務(wù)處理出現(xiàn)崩潰的情況更多一些。
作者: jiang1013nan    時間: 2011-01-11 15:30
回復(fù) 48# swxlion


    64位,8核,16G內(nèi)存
作者: jiang1013nan    時間: 2011-01-11 15:32
該版內(nèi)有很多牛人額。繼續(xù)學(xué)習,繼續(xù)接受大家的BS哈。

繼續(xù)去找工作哈。
作者: 網(wǎng)鬼    時間: 2011-01-11 17:55
拜讀學(xué)習。。。
作者: logicBaby    時間: 2011-01-11 23:28
多線程。。。一旦core掉就悲劇了。。。。。。

所以我們的都是多進程的,而且有專門的維護進程定期監(jiān)控各任務(wù)進程的狀態(tài)。

我們的模型很簡單,tcpSvr接到鏈接后派生相應(yīng)的XXXTask進程完成請求的功能,完成后推出;蛘呖梢灶A(yù)先啟動數(shù)個XXXTask進程等待tcpSvr的任務(wù)分派。
作者: gvim    時間: 2011-01-12 00:24
本帖最后由 gvim 于 2011-01-12 00:25 編輯
多線程。。。一旦core掉就悲劇了。。。。。。

所以我們的都是多進程的,而且有專門的維護進程定期監(jiān)控各 ...
logicBaby 發(fā)表于 2011-01-11 23:28


簡單的異常監(jiān)控,如果是unix下的采用父子模式,我目前用的一種監(jiān)控方案是用子進程事件來管理,比如user1,user2,SIGCHLD,父進程就可以作為各子進程的維護進程。這樣不用定期,反正子進程有異常了事件就過來了。
當然,這樣做是比較粗略的監(jiān)控方式。如果要做精細監(jiān)控就不合適了。
作者: gvim    時間: 2011-01-12 01:19
呵呵,請教一個問題,多線程,多進程,相當于單線程有什么優(yōu)勢?通訊性能更高?還是程序的處理邏輯更簡單?givm熊能否說點詳細的感受。謝謝
如果用單線程的話,都不需要進程的切換
duanjigang 發(fā)表于 2011-01-03 10:22


優(yōu)勢不少,劣勢在內(nèi)存上。
一般用途的通訊服務(wù)器必然涉及并發(fā)處理,所以很難看到有單線程的通訊服務(wù)產(chǎn)品。只要涉及并發(fā),不管是進程還是線程都要切換。比較新的unix/linux基本切換開銷相差很小,當然并不是說沒有差距。我測過適合我的服務(wù)負載的吞吐差別不大,PC 4核4G,測試目標好像是2000還是3000并發(fā),記不太清楚了。
摩爾定理也是設(shè)計上的預(yù)測,如果可以通過加強機器性能,我寧愿選擇代碼的維護,擴展和進程任務(wù)的相對單一性。
就如同用爛的OOP一樣,更多的設(shè)計增加了層,也增加了復(fù)雜性。當然,依據(jù)設(shè)計對象不同也可能是必須的。
作者: 還魂僵尸    時間: 2011-01-13 09:04
接著6樓的問題。
  既然只讀取的操作不能發(fā)現(xiàn)連接的斷開,為什么不增加一個發(fā)送操作?是的,這個想法很好, ...
duanjigang 發(fā)表于 2011-01-02 11:56



    這個說白了就是一個心跳檢測?如果用TCP,個人比較傾向于用TCP本身的心跳,這樣,服務(wù)器和客戶端可以分別自己選擇是否處理心跳,交給傳輸協(xié)議自己處理吧……
作者: 一介村夫    時間: 2011-01-13 10:46
這個說白了就是一個心跳檢測?如果用TCP,個人比較傾向于用TCP本身的心跳,這樣,服務(wù)器和客戶端 ...
還魂僵尸 發(fā)表于 2011-01-13 09:04



    這個心跳太弱了,拔網(wǎng)線之類的沒法檢測。
作者: duanjigang    時間: 2011-01-13 11:29
還有人對ICE這個中間件使用過的沒?說說使用感受和自己的做法。
這個話題已經(jīng)收集了不少意見和看法,過幾天籌劃下,發(fā)起一個通訊類中間件實踐的項目,歡迎大家踴躍參與喔
也可以就這個中間件的功能和自己的設(shè)計方法發(fā)表意見。
作者: wheniwasyoung    時間: 2011-01-14 09:20
回復(fù)  duanjigang


  是的,沒錯。

通訊層就是類似于數(shù)據(jù)中間件,負責client與業(yè)務(wù)處理層面的數(shù)據(jù)接 ...
jiang1013nan 發(fā)表于 2011-01-11 15:21



    為什么UDP就不太可行呢,我覺得UDP一樣,同樣通訊層跟業(yè)務(wù)層分開,對于大數(shù)據(jù),可以接收后組包
作者: 賀蘭云天    時間: 2011-01-14 10:08
為什么UDP就不太可行呢,我覺得UDP一樣,同樣通訊層跟業(yè)務(wù)層分開,對于大數(shù)據(jù),可以接收后組包
wheniwasyoung 發(fā)表于 2011-01-14 09:20



    恩,可以的,UDP自己再分包?組包?么非又要用UDP實現(xiàn)一個可靠的流式傳輸?:wink:
作者: wucailiuxing    時間: 2011-01-14 11:04
UDP傳輸進行分包的方式 有兩種情況是必須要考慮的 一種就是接收的包順序錯亂,這種情況還是比較好處理的 第二種情況就是包丟失 這個情況處理起來比較復(fù)雜
作者: wheniwasyoung    時間: 2011-01-14 16:58
UDP傳輸進行分包的方式 有兩種情況是必須要考慮的 一種就是接收的包順序錯亂,這種情況還是比較好處理的 第 ...
wucailiuxing 發(fā)表于 2011-01-14 11:04



   要實現(xiàn)重發(fā)機制
作者: yan8790511    時間: 2011-01-15 01:27
mark,坐看高手論道
作者: gawk    時間: 2011-01-15 14:16
第二種雙線程的方式已經(jīng)是一種不錯的模型了,在實際中應(yīng)用也不少,上面量段文字和圖片說明了服務(wù)端和客戶端 ...
duanjigang 發(fā)表于 2011-01-02 11:39

man recv
If  no messages are available at the socket, the receive calls wait for
       a message to arrive, unless the socket is nonblocking  (see  fcntl(2)),
       in  which case the value -1 is returned and the external variable errno
       is set to EAGAIN or EWOULDBLOCK.  The receive calls normally return any
       data  available,  up  to  the requested amount, rather than waiting for
       receipt of the full amount requested.


RETURN VALUE
       These calls return the number of bytes received,  or  -1  if  an  error
       occurred.   The  return  value will be 0 when the peer has performed an
       orderly shutdown.


ERRORS
       These are some standard errors generated by the  socket  layer.   Addi鈥
       tional  errors may be generated and returned from the underlying proto鈥
       col modules; see their manual pages.

       EAGAIN or EWOULDBLOCK
              The socket is marked nonblocking and the receive operation would
              block, or a receive timeout had been set and the timeout expired
              before data was received.  POSIX.1-2001 allows either  error  to
              be  returned for this case, and does not require these constants
              to have the same value, so a portable application  should  check
              for both possibilities.
作者: shtr    時間: 2011-01-23 02:36
我不贊成樓上各位所說的用進程取代線程以防止異常終止的情況,可能是我代碼寫的少,不明白為什么會發(fā)生異常終止。且不說這個,個人覺得好的架構(gòu)應(yīng)該是平臺無關(guān)的,在Windows平臺,如何實現(xiàn)fork?CreateProcess?另外,個人喜歡LF線程池模型,簡單,穩(wěn)定。
作者: duanjigang    時間: 2011-01-23 11:42
我不贊成樓上各位所說的用進程取代線程以防止異常終止的情況,可能是我代碼寫的少,不明白為什么會發(fā)生異常 ...
shtr 發(fā)表于 2011-01-23 02:36



    從科研的角度講不應(yīng)該出現(xiàn)異常終止,那就是對代碼要求考慮到一切情況,而且進行處理。從工程的角度講,還是要考慮的。
我同意你的架構(gòu)討論平臺無關(guān)的東西這種說法。不過線程和進程的概念本來在windows和linux都是支持的。只是實現(xiàn)不一樣而已,而接口都差不多是一樣的形式
作者: 一介村夫    時間: 2011-01-23 13:37
關(guān)于線程和進程,從來沒有說誰只能用來干什么,就像你用牛刀殺雞,也未嘗不可,方便不方便、順手不順手,自己感覺就是了。
看一看經(jīng)典的教科書,講線程部分的舉例,都是用的生產(chǎn)者/消費者模型,從來沒有用多通道并行模型的。再看看經(jīng)典的開源軟件,比如apache之類的,也都是用多進程而不是多線程的。
在很長一段時間里,我也同樣對多進程和多線程之間的區(qū)別沒有概念,直到有一天設(shè)計一個產(chǎn)品時我忽然明白了,多線程和多進程應(yīng)該是面向不同應(yīng)用模型的,它們的設(shè)計出發(fā)點就有不同,是用來干不同的事情的。于是我在這里說出來,就是希望別人少走這樣的彎路。
如果你一時還接受不了,那就在以后的工作中慢慢摸索和體會吧。
作者: ruifengzhangyi    時間: 2011-01-25 10:10
有個問題想請教ls各位大拿
采用第一種模型
while(1)
{
accept()
pthread_create()
}
是否存在一些 ...
ruifengzhangyi 發(fā)表于 2011-01-11 14:48



    這個問題難道就沒有人知道嗎?大拿們。
作者: duanjigang    時間: 2011-01-25 10:59
本帖最后由 duanjigang 于 2011-01-25 11:02 編輯
有個問題想請教ls各位大拿
采用第一種模型
while(1)
{
accept()
pthread_create()
}
是否存在一些 ...
ruifengzhangyi 發(fā)表于 2011-01-11 14:48



    呵呵,有兩點請斟酌:
第一:是否應(yīng)該使用多線程來處理每個連接的請求?
第二:是否應(yīng)該動態(tài)創(chuàng)建線程來處理每個請求?為什么不在初始化時創(chuàng)建好一個線程組,在接受連接的時候只是去分配任務(wù)給線程,這樣效率高點吧。

關(guān)于第一個問題,我現(xiàn)在的做法是數(shù)據(jù)的接收和發(fā)送各用一個進程,因為他們獨立,并不存在什么協(xié)作關(guān)系。(這大抵也是按照村夫說的原則來考慮的吧)
數(shù)據(jù)處理,是用別的進程來完成,也就是說,我并不支持用多線程來處理請求或者數(shù)據(jù),具體原因,參考“一介村夫”等人的回帖。

關(guān)于第二個問題:我以前做過一個程序采用的是多線程處理,目標就是通過多線程來自動登錄2000臺服務(wù)器,檢查這些機器上配置文件是否正常。
一開始想到動態(tài)線程,就覺得麻煩,因為我寫代碼喜歡按部就班的步驟,先設(shè)置初始狀態(tài),然后開啟工作狀態(tài)最后是結(jié)束狀態(tài)。而且對于所有模塊都是這個原則,如果在數(shù)據(jù)已經(jīng)到來時,創(chuàng)建線程,初始線程的狀態(tài),這樣對我個人來說,感覺邏輯很亂,而且動態(tài)創(chuàng)建線程對于響應(yīng)要求較高的應(yīng)用是有效率問題的。
我當時的做法是:2000臺機器,配置文件中設(shè)置線程個數(shù),比如50個,然后每個線程能分配40個節(jié)點,然后給每個線程都分配了獨立的任務(wù)節(jié)點來存儲數(shù)據(jù),這樣就能達到完全的并發(fā)獨立的去執(zhí)行,一臺機器的執(zhí)行任務(wù)需要3秒鐘,40個節(jié)點最快120秒,當然最后實際時間是4分鐘多(我想這是由于CPU個數(shù)不足50個,不能達到完全的并發(fā)和網(wǎng)絡(luò)資源的限制引起的吧?),不過這個結(jié)果對我來說已經(jīng)很好了。

說面得瑟了這么多,歸根結(jié)底一個目標,設(shè)計程序時,盡量避免動態(tài)的開銷和申請資源,在初始化時把能做的事情做完,這樣可能你就能對程序執(zhí)行的結(jié)果和時空消費做出估算了。而且也利于程序的穩(wěn)定。呵呵
作者: duanjigang    時間: 2011-01-25 11:02
我提到的那個多線程應(yīng)用的實例在這里
http://linux.chinaunix.net/bbs/thread-1028015-1-1.html
可以參考下,或者給提出建議,謝謝
作者: dreamice    時間: 2011-01-25 11:06
呵呵,有兩點請斟酌:
第一:是否應(yīng)該使用多線程來處理每個連接的請求?
第二:是否應(yīng)該動態(tài)創(chuàng) ...
duanjigang 發(fā)表于 2011-01-25 10:59



    很贊成段英雄的觀點。
其實感興趣的可以研究一下apache,nginx等web服務(wù)器的處理機制,充分利用了進(線)程池,內(nèi)存池的機制,也就是在初始化的時候,就創(chuàng)建一定數(shù)量的進(線)程,當請求服務(wù)到達的時候,不必再去為每個請求創(chuàng)建進(線)程來處理。同時,所創(chuàng)建的進(線)程資源還可以重復(fù)利用,即一個進程處理完一個請求后,并不直接退出,可接著處理后續(xù)的請求服務(wù)。這樣可以大大的減少進程的創(chuàng)建和銷毀帶來的系統(tǒng)開銷,從而極大的提高效率。
很多時候,如果系統(tǒng)資源緊張,可能導(dǎo)致進程創(chuàng)建失敗,內(nèi)存分配失敗。因此,預(yù)先創(chuàng)建這樣的“池”,不僅有利于對服務(wù)資源的統(tǒng)一管理,更有利于其可靠性方面的管理。
作者: duanjigang    時間: 2011-01-25 11:23
呵呵,聽dreamice說apache或許是用多進程負責通訊,也就是說接受到的socket能傳遞個子進程進行數(shù)據(jù)收發(fā)的繼續(xù),不知道這個是否真的可以,而且性能如何?
有空做個試驗。
我看過下載加速器axel代碼,知道它是用單進程多連接來實現(xiàn)通訊的,也就是說通訊是一個進程負責的。
不知道跟多進程通訊的差別在哪?
有知曉的前輩能否說兩句?
作者: ruifengzhangyi    時間: 2011-01-25 16:52
呵呵,有兩點請斟酌:
第一:是否應(yīng)該使用多線程來處理每個連接的請求?
第二:是否應(yīng)該動態(tài)創(chuàng) ...
duanjigang 發(fā)表于 2011-01-25 10:59



    很給力啊,多謝!
作者: duanjigang    時間: 2011-01-26 22:12
這個是我在最近打算換工作,總結(jié)以前項目的時候隨便畫的。

服務(wù)器主要分為兩個層次:通訊層和業(yè)務(wù)處 ...
jiang1013nan 發(fā)表于 2011-01-09 23:45



    34樓的模型貌似有些復(fù)雜,呵呵。
從這個帖子的討論中,我越發(fā)覺得數(shù)據(jù)的收和發(fā)應(yīng)該分開成兩個進程。
用兩個線程來負責收發(fā),一個線程負責接受連接這種做法是否為了利用公共的連接描述符??也就是說到一個主機使用的是一條連接負責數(shù)據(jù)收發(fā),還是收發(fā)各一條連接??
另外,用epoll的話,是不是連接接受線程和數(shù)據(jù)接收線程能合并在一起了?
作者: CU第一菜    時間: 2011-01-27 08:57
34樓的模型貌似有些復(fù)雜,呵呵。
從這個帖子的討論中,我越發(fā)覺得數(shù)據(jù)的收和發(fā)應(yīng)該分開成兩個進 ...
duanjigang 發(fā)表于 2011-01-26 22:12



    epoll并沒有改變傳統(tǒng)的select或poll等處理方式。大多數(shù)模型還是一個通信控制線程,多個數(shù)據(jù)處理線程。
作者: duanjigang    時間: 2011-01-27 09:41
epoll并沒有改變傳統(tǒng)的select或poll等處理方式。大多數(shù)模型還是一個通信控制線程,多個數(shù)據(jù)處理線 ...
CU第一菜 發(fā)表于 2011-01-27 08:57



    數(shù)據(jù)處理是獨立的,是不是用進程更好些?因為它們之間沒有什么需要協(xié)作的
作者: CU第一菜    時間: 2011-01-27 09:45
數(shù)據(jù)處理是獨立的,是不是用進程更好些?因為它們之間沒有什么需要協(xié)作的
duanjigang 發(fā)表于 2011-01-27 09:41



    進程和線程沒有太大的本質(zhì)區(qū)別,linux下個人偏好還是進程好,因為線程的話,如果主線程掛掉,會導(dǎo)致子線程也崩潰,可能出現(xiàn)一些異常。
也不能說完全沒有協(xié)作,比如說通信請求到達,需要指派給某個具體的進程來處理,這就是相應(yīng)的協(xié)作關(guān)系了。
作者: duanjigang    時間: 2011-01-27 10:06
比如說通信請求到達,需要指派給某個具體的進程來處理,這就是相應(yīng)的協(xié)作關(guān)系了。

CU第一菜 發(fā)表于 2011-01-27 09:45


這個指的是父進程把接收到的連接套接字傳遞給子進程繼續(xù)通訊嗎??
這樣的話開銷會不會很大?我意思通訊數(shù)據(jù)接收一個進程就夠了,數(shù)據(jù)處理讓多個進程來完成···
作者: CU第一菜    時間: 2011-01-27 10:20
這個指的是父進程把接收到的連接套接字傳遞給子進程繼續(xù)通訊嗎??
這樣的話開銷會不會很大?我 ...
duanjigang 發(fā)表于 2011-01-27 10:06



    設(shè)計的原則我覺得可以參考nginx,主進程只負責通信控制,數(shù)據(jù)處理有子進程來完成。
如果如版主大牛說的父進程進行通訊,那如果多個某些通信要進行多次交互,第一次數(shù)據(jù)處理由子進程A完成,而后續(xù)的數(shù)據(jù)交互處理,是不是可能再由主進程分派給其他子進程來完成了?
apache里面似乎是一個子進程負責處理完一個完整的tcp連接通信(待核實),讓子進程體現(xiàn)會話處理的完整性,是不是也是一種較好的方式。
作者: dreamice    時間: 2011-01-27 10:24
這個指的是父進程把接收到的連接套接字傳遞給子進程繼續(xù)通訊嗎??
這樣的話開銷會不會很大?我 ...
duanjigang 發(fā)表于 2011-01-27 10:06



  英雄:  通信的開銷應(yīng)該通過其通信方式來判定吧,設(shè)計一個比較優(yōu)化的方式,可能效率還是很高的。
作者: CU第一菜    時間: 2011-01-27 12:13
如果數(shù)據(jù)的收發(fā)走兩條連接的話,我們完全可以把通訊只用一個進程來做,數(shù)據(jù)處理多個子進程來實現(xiàn) ...
duanjigang 發(fā)表于 2011-01-27 10:33



    如果數(shù)據(jù)發(fā)送是以接收到的數(shù)據(jù)為判斷前提的,那還是存在數(shù)據(jù)接收和發(fā)送之間的通信同步了。個人感覺,以tcp連接會話為單位來做為進程處理更合理一些。
作者: 執(zhí)一    時間: 2011-01-27 13:47
apache中用計分板的方式實現(xiàn)父進程和子進程之間的通信,記分板有點類似于共享內(nèi)存。主進程和子進程之間又是通過管道來作為控制的,比如說主進程要結(jié)束子進程,子進程要向父進程報告錯誤等。
作者: dreamice    時間: 2011-01-27 14:58
apache中用計分板的方式實現(xiàn)父進程和子進程之間的通信,記分板有點類似于共享內(nèi)存。主進程和子進程之間又是 ...
執(zhí)一 發(fā)表于 2011-01-27 13:47



    apache的多進程處理圖

作者: duanjigang    時間: 2011-01-27 15:05
多謝江總分享,還沒看apache的代碼,看這個圖暫時沒啥深切體會,只是覺得跟我目前做的模型很像:wink:
作者: dreamice    時間: 2011-01-27 16:03
多謝江總分享,還沒看apache的代碼,看這個圖暫時沒啥深切體會,只是覺得跟我目前做的模型很像
duanjigang 發(fā)表于 2011-01-27 15:05



    跟你的機制可能差異還是很大。

apache的主進程只負責控制,在初始化時創(chuàng)建一堆子進程,子進程通過記分牌和管道與主進程通信。
主進程除了控制子進程外,不做通信處理。子進程通過競爭獲得監(jiān)聽權(quán),然后進行一系列的處理,因此apache的進程是負責一系列的連接處理的。這樣避免了進程間通信,效率還是很可觀的。
作者: 執(zhí)一    時間: 2011-01-27 16:13
跟你的機制可能差異還是很大。

apache的主進程只負責控制,在初始化時創(chuàng)建一堆子進程,子進程 ...
dreamice 發(fā)表于 2011-01-27 16:03



    apache的業(yè)務(wù)處理相對單一,只針對http,且http本身無狀態(tài)的特性。
如果是多業(yè)務(wù)復(fù)雜的進程池處理模型,該方案就不一定可行了。
作者: duanjigang    時間: 2011-01-27 16:58
apache的業(yè)務(wù)處理相對單一,只針對http,且http本身無狀態(tài)的特性。
如果是多業(yè)務(wù)復(fù)雜的進程池處 ...
執(zhí)一 發(fā)表于 2011-01-27 16:13



    嗯,對對對,剛才在QQ跟dreamice就聊到這個了,對于未知業(yè)務(wù)的數(shù)據(jù)通訊,這樣做是不行的
作者: 執(zhí)一    時間: 2011-01-27 17:10
嗯,對對對,剛才在QQ跟dreamice就聊到這個了,對于未知業(yè)務(wù)的數(shù)據(jù)通訊,這樣做是不行的:mrgreen ...
duanjigang 發(fā)表于 2011-01-27 16:58



    期待版主大牛的模型
作者: duanjigang    時間: 2012-10-07 14:08
再溫習下
作者: bingye1086    時間: 2012-11-06 11:24
回復(fù) 94# duanjigang
花了好長時間看完了這篇貼子,考慮只用C語言的情況下總結(jié)了三種情況,可能總結(jié)的不對,
1、單進程,多線程,每個線程負責一個客戶端的數(shù)據(jù)的接收發(fā)送處理
2、單進程,多線程,一個連接線程,一個數(shù)據(jù)處理線程,使用遍歷的方式處理所有連接
以上兩種模型在一般的使用環(huán)境中,在帖子里好像不被推薦
3、多進程,一個進程負責數(shù)據(jù)的發(fā)送接收,管理網(wǎng)絡(luò)連接,一個進程負責網(wǎng)絡(luò)數(shù)據(jù)的處理


另外,帖子中提到,現(xiàn)在進程和線程切換消耗資源差不多,但好像都是用在服務(wù)器上,所以問一下大牛在嵌入式中,這兩種切換的消耗是否有明顯的差距?


   
作者: tkchks    時間: 2014-07-09 19:18
java怎么實現(xiàn)多進程?
作者: BetonArmEE    時間: 2014-10-11 19:45
提示: 作者被禁止或刪除 內(nèi)容自動屏蔽
作者: mousexqshe    時間: 2015-01-07 16:25
留個記號,以后學(xué)習。
作者: wlmqgzm    時間: 2015-10-30 14:58
好吧, 我來晚了,
[C++] ASIO 無鎖, 高并發(fā),高可靠網(wǎng)絡(luò)架構(gòu),抗DOS,無鎖內(nèi)存數(shù)據(jù)庫, 奔騰雙核CPU32.5萬QPS ECHO
http://72891.cn/thread-4189684-1-1.html
作者: mousexqshe    時間: 2016-03-29 11:28
我是來學(xué)習的。




歡迎光臨 Chinaunix (http://72891.cn/) Powered by Discuz! X3.2