2012-11-29 43 views
8

我目前正在開發一個簡單的P2P網絡作爲練習。網絡中的每個節點都會將心跳發送到其他節點的子集,以便能夠檢測已離開網絡的節點。除了心跳數據包之外,當新節點加入/離開網絡時,當他們想要查找資源(小文本文件)等時,我會發送數據包。所有數據包都是UDP數據包。處理很多傳入數據包的最佳方法

每當我收到一個數據包,我開始一個新的線程來處理特定數據包。然而,我擔心的是在一個應用程序生命週期中開始的線程數量增加了很多(尤其是因爲心跳)。 (也有我想避免的死鎖之類的風險)。

我想到有一個隊列或者我把所有的報文,並有一個單獨的線程處理所有的數據包一次一個從隊列(類似生產者 - 消費者模式)的東西。我希望數據包得到快速處理,因此發送者不會認爲數據包丟失。

什麼是處理很多不同的傳入數據包,而無需啓動爲他們每個人一個新的線程的最佳方式?我應該用我擁有的東西,生產者消費還是不同的東西?

+1

當然。使用生產者 - 消費者和LinkedList。我能想到的最簡單的方法。 – DankMemes

+0

你可以從你自己提到的方式開始,做一些基準,然後嘗試最新的東西,比如「Disruptor」(http://lmax-exchange.github.com/disruptor/),然後再做一些基準。 –

+1

它可能有助於量化「許多不同的傳入數據包」......相對而言,當現代系統通常可以處理每秒數百到數千個數據包(取決於您的NIC的數量和類型)時,心跳應該不會太多。我懷疑心跳可能會在幾十分鐘的範圍內... – twalberg

回答

0

處理一個數據包需要多長時間?

對於ping那些它可能更快,只是處理它們,因爲他們收到,你可以把別人共享數據結構是這樣的一個特定的阻塞隊列,所以當隊列爲空時,工作線程等待新工作,當一個新工作被添加時,一個線程被喚醒並且將完成工作。

可能開始每包一個線程使你消耗的啓動和停止線程比實際做的工作更多的時間。

如果對於所有類型的數據包來說,響應數據包所要做的事情並不那麼耗時,那麼可能會發生這樣的情況,即隊列和調度線程的鎖所花費的額外時間會使您的程序變得更慢而不是更快。

在任何情況下使用線程池,在一開始啓動的工人。如果您希望可以根據過去幾分鐘的負載動態地增加或減少工作線程的數量。

+0

時間稍有不同。大多數數據包都是快速處理的,但有些操作涉及到新數據包的發送和期待響應。但是我想我會和線程池和隊列一起去。謝謝。 – Wondering

0

我會用一個event driven architecture。爲每個數據包創建一個新的線程是不可擴展的,所以這將工作到一定的工作量,但有一點它不會工作了。你可以比較一下像Facebook聊天這樣的聊天程序,其中消息是數據包。 事件驅動的體系結構可以擴展,恕我直言,你正在尋找什麼。只要做一些Google搜索,那裏有許多編程語言的庫,所以只需爲您選擇合適的一個(我喜歡在Erlang,Scala,C或Python中這樣做)。

編輯:好的,沒有看到java標籤。但語言並不重要。

看看這個鏈接,例如: http://www.nightmare.com/medusa/async_sockets.html

我覺得這是一個相當不錯的一個到達事件驅動編程的想法。

+0

但他使用UDP,所以他可能只有一個文件描述符。 – LtWorf

+0

這並不排除使其異步的可能性。尋找非阻塞套接字,異步I/O或甚至事件驅動套接字(基本上描述所有相同的想法)。 – Cravid

+0

我知道這樣做還是有可能的,但我不確定在這種特殊情況下值得一提。 – LtWorf