發現你的用詞有誤。正確的用詞才會有準確的討論,準確的討論才可能導出適當的答案。
服務端會創建一個執行緒 專門讀取此client的IO事件
當沒有任何可讀的數據或是數據還沒讀完 則此執行緒將會掛起 (即所謂的阻塞狀態?)
等到數據讀完 服務端參考數據之後 服務端就會安排client要做什麼事情或是一些業務的處理..
做完要做的事情之後 再反覆掛起 讀數據..
小型的服務器或許用這樣的架構是不錯 淺顯易懂 理解簡單(至少我能理解XD) 但是當達到大量的連接處理業務時
排山倒海的執行緒 有可能會讓服務器硬體資源吃不消 導致崩潰等等...
所以我在網路上查詢了相關資訊 發現了NIO這玩意
NIO與IO我看起來的差別是 NIO對於所有客戶端的IO事件採取了一個執行緒 來管理處理所有客戶端的IO事件
上面我提到的 IO模型是一個客戶端連接 開一個執行緒 來處理IO事件
NIO模型我理解的是一個執行緒處理所有客戶端的IO事件
在上這段裡的 IO 與 NIO 其實是二組 API,只是他們各自提供了 Socket 與 non-blocking Socket。
所以,需要用 non-blocking Socket 時,就會用到 NIO 提供的功能。
另外,block 的動作是針對目前你所在的 thread 來說,像寫個簡單的 console application。
它可能只有一個 main thread,如果你寫 GUI application,它會再多出 GUI 相關的 thread。
由上面的描述可以道,我們能因為需要在程式內建出若干 thread。
不管是不是使用 non-blocking Socket,我們都可以將它跑在另一個 thread。
想像一下,你寫了一個 Facebook 桌面版的 app,它有 GUI thread 與程式本身的 main thread。
GUI 上也許有不同的 TAB,使用者按了『最新動態』TAB,覺得很久沒回應,想按『塗鴨牆』但程式不理他。
一整個像當掉一樣。
我們可以合理猜測:要透過網路連線的部分『佔用』GUI thread,
所以 GUI 沒有時間理會使用者要切換 TAB 的要求。
這也是為什麼製作 GUI 的課程內,常會明確表示 GUI thread 內不要有非 GUI 操作的動作,這些動作應該放在不同的 thread。
例如:網路連線。實作上,就是由 GUI thread 開一個新的 thread,它會做網路資料讀取。
但我的疑問來了
如果真的可以用這麼少的資源開銷來管理這麼多client IO事件
那對於client來說 會不會有不順暢的情形發生?
我的理解是 NIO是對每個client做"IO事件"做輪詢 一個一個來處理
如果當前連接有10000個client 當輪詢進度到第5XXX個時
5XXX前面幾個剛好又有IO數據事件來到時 那這樣會不會有處理不順暢的問題產生呢?
IO與NIO迷思具體性的差別除了"資源的消耗"以外 以及"IO事件讀取響應順暢度"的問題
那我們到底該怎麼看這些問題 該怎麼去選擇去處理呢?
現在你的認知是:使用 non-blocking Socket 只能配合一個 thread。
你應該想成使用 non-blocking Socket 有機會讓你選擇只用一個 thread,是不是要開更多 thread 可以看使用量來決定。
若是使用 blocking Socket,為了不讓目前的 thread 停止動作(例如:GUI application)
你必需將 Socket 的讀寫放到不同的 thread 上,它至少要 1 個 client (或一組 Socket)開一個 thread。
一個是有選擇,一個是沒選擇(或接受程式沒有回應)。 |