圖解通用網絡IO底層原理、Socket、epoll、用戶態內核態······

LInux 操作系統中斷

什么是系統中斷

這個沒啥可說的,大家都知道;

CPU 在執行任務途中接收到中斷請求,需要保存現場后去處理中斷請求!保存現場稱為中斷處理程序!處理中斷請求也就是喚醒對應的任務進程來持有CPU進行需要的操作!

有了中斷之后,提升了操作系統的性能!可以異步并行處理很多任務!

  • 軟中斷(80中斷)

由CPU產生的;CPU檢查到程序代碼段發生異常會切換到內核態;

  • 硬中斷

由硬件設備發起的中斷稱為硬中斷!可以發生在任何時間;比方說網卡設備接收到一組報文;對應的報文會被DMA設備進行拷貝到網卡緩沖區!然后網卡就會向CPU發起中斷信號(IRQ):

CPU收到信號后就會執行網卡對應的中斷處理程序!

內核在系統中斷時做了什么事

每種中斷都有它對應的中斷處理程序;

對應到內核的某一個代碼段;

CPU接收到中斷后;首先需要將寄存器中數據保存到進程描述符!PCB!

隨后切換到內核態處理中斷處理程序!執行網卡的程序;

執行完畢之后切換到用戶態,根據PCB內容恢復現場!然后就可繼續執行代碼段了!

硬件中斷觸發的過程

中斷請求寄存器: 保存需要發送中斷請求的設備記錄!

優先級解析器:中斷請求是有優先級之分的,因為CPU不能同時執行多個中斷請求!

正在服務寄存器:正在執行的請求!比方我正在打字,這里面記錄的就是鍵盤IRQ1 !

操作系統啟動時需要將硬件向量值與處理程序地址進行映射!當硬件發送中斷信息時只會發送向量值,通過匹配找到對應的處理程序!

Socket基礎

Socket讀寫緩沖區機制

所謂socket,在底層也無非就是一個對象,通過對象綁定兩個緩沖區,也就是數據隊列,然后調用系統API對這兩個緩沖區的數據進行操作罷了!

發數據;用戶態轉內核態,將數據拷貝到send緩存區,然后調用write系統調用將數據拷貝到網卡,再由網卡通過TCP/IP協議進行數據包的網絡發送!

socket兩種工作模式

  • BIO

總結:讀數據讀不到就一直等,發數據發不了就一直等!

  • NIO

讀數據讀不到就等一會再讀,取數據取不到就等一會再取!

接受端緩沖區打滿了,線程又搶占不到CPU去清理緩沖區,怎么辦!

最后發送端的數據緩沖區也會被打滿!

系統調用;用戶態------內核態

  • 系統調用:

int 0X80對應的就是系統調用中斷處理程序;向量值為128;system_call;


IRQ是有限的,不可能為每一個系統調用都分配一個向量值,所以統一使用80中斷來進行系統調用的路由!

相關視頻推薦

linux內核《epoll源碼分析》

epoll實戰揭秘-支撐億級IO的底層基石

剖析Linux內核《中斷管理技術棧》

學習地址:c/c++ linux服務器開發 /后臺架構師

需要C/C++ Linux服務器架構師學習資料加qun579733396獲取(資料包括C/C++,Linux,golang技術,Nginx,ZeroMQ,MySQL,Redis,fastdfs,MongoDB,ZK,流媒體,CDN,P2P,K8S,Docker,TCP/IP,協程,DPDK,ffmpeg等),免費分享

為什么要有這兩種狀態

指令的危險程度不一樣;

對于不同的指令,為了保證系統安全,劃分了用戶空間和內核空間;

linux中:0表示內核態,3表示用戶態!

所以:linux在創建進程的時候就會為進程分配兩塊空間;

用戶棧:分配變量,創建對象

內核棧:分配變量!

什么時候進程進行切換至內核態

硬中斷;

用戶態中代碼出現錯誤也要切換!

進程切換時都做了什么

CPU中存在很多寄存器

這些寄存器保存了進程在進行運算時的一些瞬時數據;如果現在要進行進程切換了;這些數據都需要找個地方保存起來;那么保存到哪里呢?

進程PCB:在OS創建進程的時候同時也會分配一段空間存放進程的一些信息;其中就有一個字段指向一個數據結構;叫做進程控制塊PCB:

用來描述和控制進程的運行的一個數據結構——進程控制塊PCB(Process Control Block),是進程實體的一部分,是操作系統中最重要的記錄型數據結構。

  • PCB是進程存在的唯一標志

  • 系統能且只能通過PCB對進程進行控制和調度

  • PCB記錄了操作系統所需的、用于描述進程的當前情況以及控制進程運行的全部信息

所以:在進程進行切換的時候CPU中的數據保存到了PCB中,供CPU回來時讀取恢復!

Linux select 多路復用函數

select就是一個函數:只要傳入相應的參數就能獲得相應的數據:

1、們所關心的文件描述符fd;

2、描述符中我們關心的狀態:讀事件、寫事件、等

3、等待時間

調用結束后內核會返回相關信息給我們!

做好準備的個數

哪些已經做好準備;有了這些返回信息,我們就可以調用合適的IO函數!這些函數就不會再被阻塞了;-

函數詳解

int select(int maxfdp1, fd_set *readset, fd_set *writeset, fd_set *exceptset, timeval *timeout)- maxfdp1 readset 和 wirteset中的最大有數據位
- readset  bitmap結構的位信息;保存我們需要讀取的socket序號;
- writeset 寫數據信息
- exceptset 異常信息

select函數這里不再細講,可以翻看以前的文章

將函數需要的參數準備好之后調用select;

select進行80中斷;將rset數據拷貝到內核中;查詢對應的狀態之后設置rset對應的位置值,

完成后又拷貝到用戶態中的rset;這樣一來rset里面的位信息就代表了哪些socket是準備好了的!

隨后遍歷這些位信息就可以調用read或wirte進行緩沖區的操作了!

缺點

可以看到,while死循環中每次執行都將rset重新置位;然后循環重新SET位信息;隨后才會發起請求!過程較為繁瑣且重復!

select多路復用器底層原理分析

epoll函數

了解到select的缺點后發現:select每次得到數據都要進行復位,然后又進行重復的步驟去內核中獲取信息;感覺就是很多時間都花在重復的勞動上,為了解決這個問題,linux在2.6引入epoll模型,單獨在內核區域開辟一塊空間來做select主動去做的事,select是主動查,epoll則是準備數據,線程來了直接取就行了;大大提升了性能

既然是函數,看看相關的函數實現:

實現思路:

在內核創建一塊空間;總所周知;linux下一切皆文件;所以所謂創建的空間也就是一個文件描述符fd,然后這個文件結構中有兩個指針指向另外兩個地址空間:事件隊列、就緒隊列

事件隊列:存放已經建立所有socket連接

就緒隊列:準備就緒的socket;也就是read或write的時候不用阻塞的socket;

其實epoll就像一個數據庫;里面有兩個數據表;一個放連接列表;一個放準備就緒的連接列表;

既然有這兩個隊列;就要涉及到增刪查;這就是另外兩個函數的來由;

創建epoll空間
int epoll_create(int size);int epoll_wait(int epfd, struct epoll_event *events, int maxevents, int timeout);

int epoll_ctl(int epfd, int op, int fd, struct epoll_event *event);

對事件隊列進行增刪改:

epfd : epoll的文件描述符號:因為內核中可能有多個epoll

op : 參數op有以下幾個值: EPOLL_CTL_ADD:注冊新的fd到epfd中,并關聯事件event; EPOLL_CTL_MOD:修改已經注冊的fd的監聽事件; EPOLL_CTL_DEL:從epfd中移除fd,并且忽略掉綁定的event,這時event可以為null;

fd : 表示socket對應的文件描述符。

epoll底層原理解析

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/web/23908.shtml
繁體地址,請注明出處:http://hk.pswp.cn/web/23908.shtml
英文地址,請注明出處:http://en.pswp.cn/web/23908.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

《大宅門》特別活動走進李良濟,開啟探尋中醫藥文化之旅!

《大宅門》話劇將于6月14-16日在蘇州灣大劇院上演,為了讓大家了解到中醫藥知識,6月2日,李良濟攜手蘇州灣大劇院舉辦《大宅門》特別活動“探尋中醫藥文化之旅”! 6月2日下午,大家一起走進李良濟,深度了解傳統…

vite熱更新導致的問題及解決

一、封裝axios攔截器后,每次熱更新雖然請求了一次,但是response了多次: import axios from "axios"; axios.interceptors.request.use() axios.service.interceptors.response.use()導致此問題是因為觸發了多次攔截器,相當于是給axios添加了多個攔截器,所以多次…

怎么能通過chatgpt-on-wechat獲取全部的微信聊天信息

要通過 chatgpt-on-wechat 工具獲取全部的微信聊天信息,你可以按照以下步驟操作: 安裝并配置 itchat 庫: itchat 是一個開源的微信個人號接口,可以幫助你獲取微信群聊信息。 pip install itchat登錄微信: 使用 itchat …

小白必學!場外期權的交易模式

場外期權的交易模式 隨著金融市場的深化與創新,場外期權交易作為一種靈活多樣的金融衍生品交易方式,正逐漸成為投資者關注的焦點。場外期權,顧名思義,是在非交易所市場進行的期權交易,與交易所期權有著顯著的區別。那…

Promed Bioscience—高純度膠原蛋白

Promed Bioscience——高純度膠原蛋白供應商 專于研發,忠于質量,創新驅動 AXXORA 作為Enzo life sciences公司的子公司,是歐美最大的生命科學研究信息、服務、銷售電子一站式服務平臺之一,AXXORA精選歐洲四十多家優秀的生命科學研…

Mac 使用Docker安裝Elasticsearch、Kibana 、ik分詞器、head

安裝ElasticSearch 通過docker安裝es docker pull elasticsearch:7.8.1 在本地創建elasticsearch.yml文件 mkdir /Users/ky/Documents/learn/es/elasticsearch.yml 編輯yml文件內容 http: host: 0.0.0.0 xpack.security.enabled: false xpack.security.enrollment.enabled: t…

JAVA-LeetCode 熱題-第24題:兩兩交換鏈表中的節點

思路: 定義三個指針,其中一個臨時指針,進行交換兩個節點的值,重新給臨時指針賦值,移動鏈表 class Solution {public ListNode swapPairs(ListNode head) {ListNode pre new ListNode(0,head);ListNode temp pre;wh…

docker部署fastdfs

我的鏡像包地址 鏈接:https://pan.baidu.com/s/1j5E5O1xdyQVfJhsOevXvYg?pwdhcav 提取碼:hcav docker load -i gofast.tar.gz拉取gofast docker pull sjqzhang/go-fastdfs啟動gofast docker run -d --name fastdfs -p 8080:8080 -v /opt/lijia/lijia…

antd vue a-select 搜索

數據結構 list: [{ name: "序號", id: 0, show: true },{ name: "出庫單編號", id: 1, show: false },{ name: "wbs元素", id: 2, show: true },{ name: "序號1", id: 3, show: true },{ name: "出庫單編號1", id: 4, show…

Java_Collection的其它相關知識

前置知識:可變參數 就是一種特殊形參,定義在方法,構造器的形參列表里,格式是:數據類型…參數名稱; 可變參數的好處和特點 好處:常常用來接受數據。 特點:可以不傳數據給它&#xf…

如何從小米手機傳輸文件到電腦? [5個簡單的方法]

與蘋果設備間的AirDrop或iTunes等工具相比,Android手機到PC的文件傳輸似乎不那么便捷。但小米用戶有多種應用,如Mi PC Suite和ShareMe,可以高效地進行傳輸。本文將介紹5種將小米設備文件傳輸到PC的方法,包括使用和不使用USB線的情…

深度學習_02_卷積神經網絡循環神經網絡

卷積神經網絡 1. 卷積神經網絡 神經元存在局部感受區域----感受野 . 第一個卷積神經網絡雛形----新認知機 缺點:沒有反向傳播算法更新權值,模型性能有限 第一個大規模商用卷積神經網絡----Lenet-5 缺點:沒有大量數據和高性能計算資源。 第一個…

圖解 React diff 算法

Render 階段會生成 Fiber Tree,所謂的 diff 實際上就是發生在這個階段,這里的 diff 指的是 current FiberNode 和 JSX 對象之間進行對比,然后生成新的的 wip FiberNode。 除了 React 以外,其他使用到了虛擬 DOM 的前端框架也會有類…

C++的枚舉

文章目錄 簡介枚舉的基本語法基本使用方法習題簡介 在C++中,枚舉(Enumeration)是一種數據類型,它允許程序員定義一個變量并指定它可以取的那些固定值的集合。枚舉的主要目的是提高代碼的可讀性和維護性,通過使用有意義的名稱而不是數字來表示狀態、類型或其他固定集合的值…

Kafka之Producer原理

1. 生產者發送消息源碼分析 public class SimpleProducer {public static void main(String[] args) {Properties prosnew Properties();pros.put("bootstrap.servers","192.168.8.144:9092,192.168.8.145:9092,192.168.8.146:9092"); // pros.pu…

OceanBase v4.2 特性解析:Lateral Derived Table 優化查詢

前言 從傳統規則來看,內聯視圖通常不允許引用在同一FROM子句中前面定義的表的列。但從OceanBase 4.2.2版本開始,這一限制得到了突破,允許內聯視圖作為Lateral Derived Table來定義,從而允許此類引用。Lateral Derived Table的語法…

26-LINUX--I/O復用-select

一.I/O復用概述 /O復用使得多個程序能夠同時監聽多個文件描述符,對提高程序的性能有很大幫助。以下情況適用于I/O復用技術: ? TCP 服務器同時要處理監聽套接字和連接套接字。 ? 服務器要同時處理 TCP 請求和 UDP 請求。 ? 程序要同時處理多個套接…

Facebook廣告素材如何測試?手把手教你!

廣告素材對Facebook廣告效果的影響是很大的,用對了素材,Facebook廣告的價值就越高。廣告主們通常會先通過廣告測試,根據數據反饋來挑選素材。今天就手把手教你做Facebook素材測試的技巧,讓你更有靈感和思路! 創意測試 …

Hudi CLI 安裝配置總結

前言 上篇文章 總結了Spark SQL Rollback, Hudi CLI 也能實現 Rollback,本文總結下 Hudi CLI 安裝配置以及遇到的問題。 官方文檔 https://hudi.apache.org/cn/docs/cli/ 版本 Hudi 0.13.0(發現有bug)、(然后升級)0.14.1Spark 3.2.3打包 mvn clean package -DskipTes…

使用 Django 構建動態網頁

文章目錄 創建 Django 項目和應用程序創建 HTML 模板創建視圖函數配置 URL 路由運行 Django 服務器使用 Django 模板語言 Django 是一個流行的 Python Web 框架,它能夠幫助開發人員快速構建強大的 Web 應用程序。在 Django 中,HTML 是用于呈現網頁內容的…