成人免费xxxxx在线视频软件_久久精品久久久_亚洲国产精品久久久_天天色天天色_亚洲人成一区_欧美一级欧美三级在线观看

圖文詳解io_uring高性能異步IO架構(原理篇)

開發 前端
釋放已完成IO請求只需要將CQ Ring head指針自增1指向下一個CQE即可,這樣做的目的是防止重復獲取IO請求結果。

說到高性能網絡編程,我們第一時間想到的是epoll機制,epoll很長一段時間統治著整個網絡編程江湖,然而io_uring的出現,似乎在撼動epoll的統治地位,今天我們來揭開io_uring的神秘面紗。

1.io_uring簡介

io_uring是一個Linux內核的異步I/O框架,它提供了高性能的異步I/O操作,io_uring的目標是通過減少系統調用和上下文切換的開銷來提高I/O操作的性能。

io_uring通過使用環形緩沖區和事件驅動的方式來實現高效的異步I/O操作。

io_uring的設計使得應用程序可以同時處理大量的I/O操作,從而提高系統的吞吐量和響應速度。

2.io_uring實現原理

io_uring整體架構如下:

圖片圖片

2.1基礎概念

  • SQE:提交隊列項,表示IO請求。
  • CQE:完成隊列項,表示IO請求結果。
  • SQ:Submission Queue,提交隊列,用于存儲SQE的數組。
  • CQ:Completion Queue,完成隊列,用于存儲CQE的數組。
  • SQ Ring:SQ環形緩沖區,包含SQ,頭部索引(head),尾部索引(tail),隊列大小等信息。
  • CQ Ring:CQ環形緩沖區,包含SQ,頭部索引(head),尾部索引(tail),隊列大小等信息。
  • SQ線程:內核輔助線程,用于從SQ隊列獲取SQE,并提交給內核處理,并將IO請求結果生成CQE存儲在CQ隊列。

2.2 io_uring系統調用

  • io_uring_setup():用于初始化io_uring環境,創建io_uring實例。
  • io_uring_enter():用于提交和等待io_uring操作的系統調用,可以指定提交的操作數量和等待的超時時間。
  • io_uring_register():用于注冊文件描述符或事件文件描述符到io_uring實例中,以便進行I/O操作。

2.3 liburing庫

liburing是一個用于Linux的用戶空間庫,用于利用io_uring接口進行高性能的異步I/O操作,它提供了一組函數和數據結構,使開發者能夠更方便地使用io_uring接口。

  • io_uring_queue_init:初始化一個io_uring隊列。
  • io_uring_register:將文件描述符注冊到io_uring隊列中。
  • io_uring_prep_read:準備一個讀取操作。
  • io_uring_prep_write:準備一個寫入操作。
  • io_uring_submit:提交一個或多個操作到io_uring隊列中。
  • io_uring_wait_cqe:等待一個完成的操作。
  • io_uring_cqe_seen:標記一個完成的操作已經被處理。
  • io_uring_queue_exit:關閉并釋放io_uring隊列。

2.4 工作流程

  1. 創建io_uring對象:首先,需要創建一個io_uring對象,可以使用io_uring_setup()函數來完成。
  2. 準備I/O請求:在進行I/O操作之前,需要準備相關的I/O請求??梢允褂胕o_uring_prep_XXX()系列函數來準備不同類型的I/O請求,例如io_uring_prep_read()用于讀取數據,io_uring_prep_write()用于寫入數據。
  3. 提交I/O請求:準備好I/O請求后,可以使用io_uring_submit()函數將請求提交給內核,內核會將這些請求放入一個隊列中,等待執行。
  4. 等待IO請求完成:可以使用io_uring_wait_cqe()函數來等待I/O請求的完成,一旦請求完成,內核會將完成事件放入一個完成隊列中。
  5. 獲取IO請求結果:可以使用io_uring_peek_cqe()函數來獲取完成隊列中的完成事件。然后,可以通過事件的信息來處理完成的I/O請求,例如讀取數據或者處理錯誤。
  6. 釋放IO請求結果:獲取完IO請求結果,使用io_uring_cqe_seen()函數來釋放IO請求結果,以便內核可以繼續使用。
  7. 重復執行:可以重復執行上述步驟,以處理更多的I/O請求。

3.內核實現

3.1 創建io_uring對象

圖片圖片

用戶程序通過io_uring_setup系統調用創建和初始化io_uring對象,io_uring對象對應于struct io_ring_ctx結構體對象。

io_uring_setup主要工作:

  • 創建struct io_ring_ctx對象并初始化。
  • 創建struct io_urings對象并初始化,注意此時已完成CQ和所有CQE創建。
  • 創建SQ和所有SQE并初始化。
  • 如果struct io_ring_ctx對象flags參數設置IORING_SETUP_SQPOLL,則創建SQ線程。

3.2 fd綁定io_uring對象

圖片圖片

已創建的io_ring對象需要和fd進行綁定, 以便能夠通過fd找到io_uring對象,創建一個新的file,file private_data成員指向io_ring對象,申請一個未使用的文件描述符fd,fd映射至file,并存儲在進程已打開文件表中。

注意:mmap內存映射需要用到該fd。

3.3 io_uring對象內存映射

圖片圖片

通過io_uring_setup系統調用創建完io_uring對象后,用戶程序還不能直接訪問io_uring對象,此時用戶程序需要通過mmap函數將io_uring對象SQ,CQ以及head和tail等相關內存空間映射出來。

完成mmap內存映射后,io_uring對象相關內存空間成為用戶程序和內核共享內存空間,用戶程序可以直接訪問io_uring對象,不再需要通過執行系統調用訪問,很大程度上提高了系統性能。

3.4 提交IO請求

圖片圖片

SQ Ring中有兩個成員head(頭部索引)和tail(尾部索引),頭部索引指向SQ隊列第一個已提交IO請求,尾部索引指向SQ下一個空閑SQE。

提交IO請求,只需要將tail指向的SQE填充IO請求信息,并讓tail自增1,指向下一個空閑SQE。

注意:head和tail不是直接指向SQ數組,而是需要通過head&mask和tail &mask操作指向SQ數組,mask數組為數組長度減1,因為數組有固定大小,所以需要通過&mask方式防止越界訪問數組,這種方式可以讓數組形成一個環形緩沖區。

3.5 等待IO請求完成

圖片圖片

IO請求的處理有兩種方式:

  • 方式1:SQ線程從SQ隊列中獲取SQE(已提交IO請求),并發送給內核處理。
  • 方式2:用戶程序通過io_uring_enter系統調用從SQ隊列中獲取SQE(已提交IO請求),并發送給內核處理。

從SQ隊列獲取SQE只需要獲取SQ Ring head指向的SQE,并讓head自增指向下一個SQE即可。

圖片圖片

內核處理完IO請求后,SQ線程會申請CQ Ring tail指向的CQE存儲IO請求結果,tail自增1指向下一個空閑CQE。

3.6 獲取IO請求結果

圖片圖片

用戶程序通過判斷CQ Ring head和tail之間的差值,可以檢測到是否有已完成IO請求,如果有已完成IO請求(CQE),獲取CQ Ring head指向CQE,獲取IO請求結果。

3.7 釋放已完成IO請求

釋放已完成IO請求只需要將CQ Ring head指針自增1指向下一個CQE即可,這樣做的目的是防止重復獲取IO請求結果。

io_uring為什么高效?

核心原因:io_uring通過mmap內存映射大大減少了系統調用,在高并發場景下,系統調用非常損耗系統性能。

其他原因:

  • 減少拷貝:io_uring通過共享內存減少用戶程序和內核數據拷貝。
  • 批量操作:io_uring支持批量操作,一次性可以提交多個I/O請求,減少系統調用的次數,提高系統效率。
  • 無鎖環形隊列:io_uring采用無鎖隊列實現用戶程序與內核對共享內存的高效訪問。
責任編輯:武曉燕 來源: 物聯網心球
相關推薦

2023-04-12 18:36:20

IO框架內核

2025-02-03 09:53:42

2023-02-07 19:46:35

NIOCQ內核

2023-10-20 06:26:51

Libuvio_uring

2021-07-11 23:25:29

Libuvepoll文件

2021-07-07 23:38:05

內核IOLinux

2021-07-03 08:04:10

io_uringNode.js異步IO

2020-09-30 06:44:39

存儲IO

2017-07-07 16:36:28

BIOIO模型 NIO

2024-07-12 08:42:58

Redis高性能架構

2020-06-17 16:43:40

網絡IO框架

2019-01-08 13:32:38

Nginx服務器IO復用

2021-04-09 08:54:14

Kafka源碼架構開發技術

2021-09-05 17:46:21

云計算No.jsio_uringJS

2021-06-09 10:29:23

Kafka架構組件

2010-12-22 13:17:47

Linux性能監測磁盤IO

2011-11-08 21:51:43

Linux 監控 IO

2010-05-26 18:31:51

Linux性能監控

2011-11-08 21:47:37

Linux 監控 IO

2024-08-16 21:30:00

IO網絡網絡通信
點贊
收藏

51CTO技術棧公眾號

主站蜘蛛池模板: 欧美一级片免费看 | 久久成人精品 | av官网在线 | 欧美人人 | 91免费观看 | 欧美啪啪 | 色免费在线视频 | 三级黄色片在线播放 | 国产在线观看 | 中文字幕成人av | 97伦理影院| 亚洲高清视频一区二区 | 一区二区三区av | 高清国产午夜精品久久久久久 | 国产成人自拍av | 国产婷婷在线视频 | www.五月婷婷.com | 国产精品久久久久久久久久三级 | 欧美成人一区二区 | 午夜精品久久久久久久久久久久久 | 国产成人免费视频网站高清观看视频 | 色www精品视频在线观看 | 国产永久免费 | 亚洲激情一级片 | 成人国产在线视频 | 欧美性视频在线播放 | 操久久 | 午夜三区 | 国产日韩一区二区 | 91成人在线| 亚洲中午字幕 | 欧美a区 | 免费大黄视频 | 日韩精品一区二区三区 | 日日摸夜夜爽人人添av | 国产区在线免费观看 | 国产人免费人成免费视频 | 国产激情在线观看 | eeuss国产一区二区三区四区 | 日皮视频免费 | 婷婷丁香在线视频 |