應用層在進行read,write系統呼叫時,不是物理級別的讀寫,而是快取的複製,程序緩衝區同核心緩衝區的快取複製,底層資料交換是有由作業系統核心完成,控制核心緩衝與硬體(物理裝置)之間資料交換.linux系統在系統核心只有乙個核心緩衝區,使用者程序都有獨立的緩衝區,是程序緩衝區。外部裝置的直接讀寫涉及作業系統的中斷,底層操作會對核心緩衝區進行監控,等待緩衝區達到一定數量的時候,再進行io裝置的中斷處理,集中執行物理裝置的實際io操作,這種機制提公升了系統的效能,至於什麼時候中斷(讀中斷、寫中斷),由作業系統的核心來決定,使用者程式則不需要關心.
1、同步阻塞io: 在核心進行io執行的兩個階段,使用者執行緒都被阻塞,在阻塞期間,使用者執行緒基本不會占用cpu資源,但在高併發場景下不可採用.
2、同步非阻塞io: 不斷的進行io系統呼叫,輪詢資料狀態,使用者執行緒不會阻塞,會占用大量的cpu時間,在高併發場景下,也不採可.簡稱nio.
3、 io多路復用:
系統呼叫,一種是select/epoll(就緒查詢),一種是io操作,輪詢查詢出達到io操作就緒的socket連,乙個選擇器查詢執行緒可處理成千上萬個連線,不必建立維護大量執行緒,減小系統開銷,缺點》select/epoll系統呼叫是阻塞式的,屬於同步io.都需要在讀寫事件就緒後,由系統呼叫本身負責進行讀寫,也就是說這個讀寫過程是阻塞的。
4、非同步io:aio
在核心等待資料和複製資料的兩個階段,使用者執行緒都不是阻塞的。使用者執行緒需要接收核心的io操作完成的事件,或者使用者執行緒需要註冊乙個io操作完成的**函式。非同步io有時也被稱為訊號驅動io.缺點》應用程式僅需要進行事件的註冊與接收,其餘的工作都留給了作業系統,即需要底層核心提供支援。目前windows系統下通過iocp實現了真正的非同步io,在linux系統中還不太完善。
在生產環境linux系統中,基本上都需要解除檔案控制代碼數的限制。檔案控制代碼,也叫檔案描述符。檔案描述符(file descriptor)是核心為了高效管理已被開啟的檔案所建立的索引,它是乙個非負整數(通常是小整數),用於指代被開啟的檔案。所有的io系統呼叫,包括socket的讀寫呼叫,都是通過檔案描述符完成的。
用ulimit命令,檢視單個程序能夠開啟的最大檔案控制代碼數量
ulimit -n乙個高併發的應用,併發連線數可以達到數十萬百萬千萬級別,檔案控制代碼數不夠,當單個程序開啟的檔案控制代碼數量,超過了系統配置的上限值時,會發出「socket/file:can't open so many files」的錯誤提示。
可以通過ulimit來設定這兩個引數, 注意ulimit只能作為臨時修改,系統重啟後,控制代碼數量又會恢復為預設值
ulimit -n 1000000永久修改配置,可以編輯 /etc/rc.local 開機啟動檔案,在檔案中新增如下內容,選項-s表示軟性極限值,-h表示硬性極限值
ulimit -shn 1000000終極解除linux系統的最大檔案開啟數量的限制,編輯linux的極限配置檔案/etc/security/limits.conf來解決,加入如下內容
#軟性極限軟性極限是系統警告(warning)的極限值,超過這個極限值,核心會發出警告。soft nofile
1000000
#硬性極限
hard nofile
1000000
學習理解了低層io操作的2個階段:等待資料和複製資料。加深了對四種主要io模型的理解掌握,前3種都是同步io,因為實際io操作都會阻塞應用的執行緒。僅第四種是真正的非同步io,但是依賴於系統核心的支援。這些內容為學習netty這個優秀框架打下良好的理論基礎。
書籍閱讀:《netty、redis、zookeeper高併發實戰 》 尼恩
額外理解參考:
GIT底層理解
git多用來做版本控制的工具 資料結構分為 git倉庫 文字 blob tree commit head 雜湊樹的形式 有向圖 head 指標 指向乙個分支commit commit指向有檔案tree,收錄檔案資訊等 再下面指向file,每個都有自己的hash值,一旦變更都會發生變化 index層 ...
理解高併發 序言
高併發已不是個熱詞,然而用好它並非易事,很多時候如果沒有使用得當,極容易產生適得其反的效果。本系列我將系統性的給大家分享高併發的技術要點。其具體技術點包括以下 1.我對併發程式設計的理解 2.synchronized原理及用法 3.顯式鎖的用法 4.鎖的優化技巧 5.執行緒通訊之 wait noti...
C指標的實質,對底層理解很有好處
最近對c c 指標特別感冒,就詳細的研究了下 看下面的定義 char a hello world char p hello world 1.什麼是位址 位址本身就是一種基本資料型別,它跟整數,浮點數,字元等基本型別是一樣的。指標不是型別,真正的型別是位址,指標只不過是儲存位址這種資料型別的變數。打個...