資料的傳遞需要從使用者空間或者磁碟等硬體拷貝至核心緩衝區,在從核心緩衝區拷貝至閘道器後傳輸至網路,網路暢通情況下計算機一邊向緩衝區寫資料,一邊將緩衝區的資料讀取至閘道器。
資料的接收需要從閘道器拷貝至核心緩衝區後,再從核心空間拷貝至使用者空間或者磁碟等硬體,網路暢通情況下計算機一邊將資料從閘道器接受寫入核心緩衝區,一邊將資料從緩衝區拷貝至使用者空間或者直接持久化至磁碟等。
當網路不暢通時,緩衝區被寫滿或者讀完,會產生阻塞io事件,假設叫「緩衝區滿」和「緩衝區空」事件。
傳統io在核心緩衝區觸發寫滿或者讀完事件時,會阻塞相應的處理執行緒,「緩衝區滿」會傳遞執行緒,「緩衝區空」會阻塞接收執行緒,他們分別在資料流的兩端,一端將資料寫入流,一端從流接受資料。
當網路重新通暢後,緩衝區處於非空非滿狀態時,觸發io事件,假設叫「緩衝區非滿」和「緩衝區非空」事件,傳統io在感知到此事件時會喚醒相應的處理執行緒,「緩衝區非滿」喚醒寫入執行緒,「緩衝區非空」喚醒接受執行緒。
nio對緩衝區io事件的處理不是由cpu喚醒執行緒來實現,而是將io時間的處理委託給selector物件。
nio的非阻塞實現形式在開頭的那篇部落格已經講得和好了,我這裡就不說了。
下面說下nio相對於傳統io的優勢:
傳統io在處理資料傳輸請求時,針對每個傳輸請求生成乙個執行緒,如果io異常,那麼執行緒阻塞,在io恢復後喚醒處理執行緒。在同時處理大量連線時,會例項化大量的執行緒物件。每個執行緒的例項化和**都需要消耗資源,jvm需要為其分配tlab,然後初始化tlab,最後繫結執行緒,執行緒結束時又需要**tlab,這些都需要cpu資源。
nio使用selector來輪詢io流,內部使用poll或者epoll,以事件驅動形式來相應io事件的處理。同一時間只需例項化很少的執行緒物件,通過對執行緒的復用來提高cpu資源的使用效率。
cpu輪流為每個執行緒分配時間片的形式,間接的實現單物理核處理多執行緒。當執行緒越多時,每個執行緒分配到的時間片越短,或者迴圈分配的週期越長,cpu很多時間都耗費在了執行緒的切換上。執行緒切換包含執行緒上個執行緒資料的同步(tlab同步),同步變數同步至主存,下個執行緒資料的載入等等,他們都是很耗費cpu資源的。
在同時處理大量連線,但活躍連線不多時,nio的事件響應模式相比於傳統io有著極大的效能提公升。
nio還提供了filechannel,以zero-copy的形式傳輸資料,相較於傳統的io,資料不需要拷貝至使用者空間,可直接由物理硬體(磁碟等)通過核心緩衝區後直接傳遞至閘道器,極大的提高了效能。
阻塞IO與非阻塞NIO
通常的,對乙個檔案描述符指定的檔案或裝置,有兩種工作方式 阻塞 與非阻塞 所謂阻塞方式的意思是指,當試圖對該檔案描述符進行讀寫時,如果當時沒有東西可讀,或者暫時不可寫,程式就進入等待 狀態,直到有東西可讀或者可寫為止。而對於非阻塞狀態,如果沒有東西可讀,或者不可寫,讀寫函式馬上返回,而不會等待 一種...
非阻塞IO和阻塞IO
非阻塞io和阻塞io 在網路程式設計中對於乙個網路控制代碼會遇到阻塞io 和非阻塞io 的概念,這裡對於這兩種socket 先做一下說明 基本概念 阻塞io socket 的阻塞模式意味著必須要做完io 操作 包括錯誤 才會返回。非阻塞io 非阻塞模式下無論操作是否完成都會立刻返回,需要通過其他方式...
非阻塞IO和阻塞IO
非阻塞io 和阻塞io 在網路程式設計中對於乙個網路控制代碼會遇到阻塞io 和非阻塞io 的概念,這裡對於這兩種socket 先做一下說明 基本概念 阻塞io socket 的阻塞模式意味著必須要做完io 操作 包括錯誤 才會 返回。非阻塞io 非阻塞模式下無論操作是否完成都會立刻返回,需要通過其他...