看到這張圖你能夠完全理解嗎。
相關視頻講解基于Linux epoll網絡編程細節處理:「鍊接」
網路io底層epoll:「鍊接」
提升服務器底層性能,異步解決方案:「鍊接」
1.多路複用的意思:多路複用的意思,就是在任何一路 I/O 有“事件”發生的情況下,通知應用程序去處理相應的 I/O 事件,這樣我們的程序就變成了“多面手”,在同一時刻仿佛可以處理多個 I/O 事件。
2.應用條件:
3.中斷的概念:
在CPU運行着進程A時,進程B發起一個中斷請求IRQ,中斷處理程序進行處理請求,将進程A挂起,然後運行進程B。
中斷的過程:将當前運行的進程的運行信息保存到該進程的描述符。根據進程描述符的内核态堆棧指針切換到内核态。根據來到的IRQ在中斷表裡面查找所屬的中斷處理程序。運行該中斷處理程序。(看似是進程執行的中斷,但和進程沒什麼關系)
4.硬中斷的概念:
對于計算機硬件的,一般來說是與當時CPU請求是異步的(沒關系的),比如網關來了一個報文,
5.軟中斷的理解:
CPU在執行一段代碼段是 遇到問題,進行中斷,由用戶态切換到内核态。
6.每次中斷都有其對應的中斷處理程序。
7每個進程都在用戶态和内核态擁有一個堆棧。
8.為什麼要有兩種狀态(内核态、用戶态)
内核态和用戶态的”權限不同“。防止每個程序都分配過多資源。用戶态的進程能夠訪問的資源受到了極大的控制,而運行在内核态的進程可以“為所欲為”。
一個進程可以運行在用戶态也可以運行在内核态,那它們之間肯定存在用戶态和内核态切換的過程。
打一個比方:C庫接口malloc申請動态内存,malloc的實現内部最終還是會調用brk()或者mmap()系統調用來分配内存。
9.從用戶态到内核态切換可以通過三種方式:
10.socket的小demo
11.socket底層邏輯圖
12.阻塞模式下的情況
寫
(1)要傳輸的數據大于 輸出緩沖區的大小,需要分開傳輸,還沒傳輸的挂起。
(2)輸出緩沖區TCP正在輸出别的數據,需要TCP釋放輸出緩沖區才能寫。
讀(1)如果輸入緩存區沒有數據,則系統調用的方法挂起。
(2)緩沖區數據太多,每次read隻能讀一部分,需要一直慢慢讀直到讀完
13.非阻塞模式下
文章福利 Linux後端開發網絡底層原理知識學習提升 點擊 正在跳轉 獲取,完善技術棧,内容知識點包括Linux,Nginx,ZeroMQ,MySQL,Redis,線程池,MongoDB,ZK,Linux内核,CDN,P2P,epoll,Docker,TCP/IP,協程,DPDK等等。
寫
(1)如果向輸出緩沖區寫的數據太多了 ,分批發送,但是會馬上告訴你發送了多少。
(2)如果空間為0,會馬上告訴你緩沖區滿了,由上次程序決定怎麼做。(而阻塞則會一直挂起,等待緩沖區釋放)
14.進程進行用戶态到内核态的切換過程:
1.從當前進程的描述符中提取其内核棧的ss0及esp0信息。
2.使用ss0和esp0指向的内核棧将當前進程的cs,eip,eflags,ss,esp信息保存起來,這個過程也完成了由用戶棧到内核棧的切換過程,同時保存了z暫停執行的程序的下一條指令。
3.将先前由中斷向量檢索得到的中斷處理程序的cs,eip信息裝入相應的寄存器,開始執行中斷處理程序,這時就轉到了内核态的程序執行了。
15.Linux的一切都是文件fd。
16.select函數
#include <sys/select.h>
int select(int maxfdp1, fd_set *readset, fd_set *writeset, fd_set *exceptset,struct timeval *timeout);
1)maxfdpl 最大有效位。(因為fd_set是以bitmap來保存數據的 linux默認1024位bitmap 最大有效位之後不需要檢查)
2)fd_set *readset 可讀文件描述符集
3)fd_set *writeset 可寫文件描述符集
4)fd_set *exceptset 異常文件描述符集
5)timeout 超時時間
Linux select函數的宏
#include <sys/select.h>
intFD_ZERO(intfd, fd_set *fdset);//将描述符集全部置0
intFD_CLR(intfd, fd_set *fdset);//
intFD_SET(intfd, fd_set *fd_set);//将某個位置位
intFD_ISSET(intfd, fd_set *fdset); //檢查某個位是否被置位
select函數缺點:
1)固定文件描述符1024位的bitmap,請求過大則無法描述,有大小限制
2)fd_set不可重用,每次都有重新置位
3)有用戶态到内核态切換的開銷
4)每次函數返回都需要O(n)的時間進行遍曆
17.poll函數我們将select函數的bitmap結構的fd_set變為 自己實現的pollfd
使用鍊表來進行文件描述,不存在大小限制問題。
18.epoll函數
19.同步調用、異步調用:
同步:B來向A拿取數據,B一直等到A正确交付數據。
異步:B來向A拿取數據,B見A還在準備則返回 進行自己的事情。
20.阻塞、非阻塞
A向B拿數據,C也向A要數據,C要等待 則是阻塞。
A向B拿數據,C也向A要數據,A同時服務B C 則是非阻塞。
同步與異步
同步和異步的區别最大在于異步的話調用者不需要等待處理結果,被調用者會通過回調等機制來通知調用者其返回結果。
阻塞和非阻塞
21.網絡通信例子
服務端
客戶端
我們可以看到服務端有2個方法 accept和read都在阻塞,這就是我們的BIO(同步阻塞I/O模式)
優化:我們可以使用多線程、線程池等來優化,關鍵是有很多不活躍的線程時,占用資源過多,上下文切換過多。
22.使用NIO優化通信例子(服務器端 客戶端無所謂)
23.windows的NIO是select linux的NIO底層是eqpoll。
Redis的NIO是epoll,隻能在Linux環境運行,但是有win版本,是大神修改了redis代碼。
,更多精彩资讯请关注tft每日頭條,我们将持续为您更新最新资讯!