2012-09-06 38 views
0

使用select()函數有什麼用處嗎?選擇插座編程

從我的(小)經驗來看,我傾向於認爲線程就足夠了。

所以我想知道,select()只是一個教學工具,用於那些還不知道線程的人嗎?

回答

2

考慮下面的例子。你有一箇中等繁忙的網絡服務器,像100K連接。您沒有使用select或類似的東西,因此每個連接只有一個線程,意味着100K線程很快就會成爲問題。

即使你調整你的系統,直到它允許這樣的怪物,大多數線程只會等待一個套接字。如果有一種機制讓在套接字變得有趣時通知你,這不是更好麼

換句話說,線程和select類似的機制是互補的。你只是不能用threads來代替簡單的東西select做的事情:監控文件描述符。

+0

好的。我明白你在說什麼。您能否提供使用線程和選擇客戶端 - 服務器體系結構的最佳做法? – coredump

+0

@coredump這取決於你在做什麼。 – cnicutar

+0

這是一個文件傳輸項目。服務器託管有關客戶端的數據。實際傳輸是客戶端之間的點對點傳輸。服務器只保存主機的文件和其他數據。客戶端可以接受多個連接,並且我想傳輸部分文件然後轉到另一個連接,傳輸文件的一部分等等。 – coredump

1

單線程輪詢使用,實現和(最重要的)明白要簡單得多。併發編程爲您的項目增加了巨大的智力成本:同步數據非常棘手且容易出錯,鎖定引入了許多錯誤機會,無鎖數據結構導致性能命中,並且程序流變得難以在思想上形象化(或「序列化」也許)。

相比之下,單線程輪詢(可能與epoll/kqueue而非select)爲您提供了一般非常不錯的表現(上究竟你在響應數據正在做當然依賴的),而其餘的直線前進。

特別是在Linux中,您可以使用timerfds,eventfds,signalfds和inotify-fds以及嵌套的epoll-fds,它們都坐在您的投票集中,爲您提供了一種非常統一的處理各種「異步」事件。如果最終需要更多的性能,那麼通過同時運行多個輪詢器可以獲得單點並行性,並且內核爲您提供的大部分數據同步,它承諾只有一個單線程在事件中接收到成功的輪詢準備就緒。