哪家網(wǎng)站建設(shè)服務(wù)好網(wǎng)絡(luò)廣告策劃與制作
基于異步IO的io_uring
1. io_uring的實現(xiàn)原理
io_uring使用了一種異步IO機制,它通過一對環(huán)形緩沖區(qū)(ring buffer)實現(xiàn)用戶態(tài)于內(nèi)核態(tài)之間的高效通信,用戶只需將IO請求放入提交隊列,當(dāng)內(nèi)核完成IO請求時,會將結(jié)果放入完成隊列,然后用戶從完成隊列中提取結(jié)果并進行后序處理。
io_uring中的兩個隊列是映射到用戶態(tài)的共享內(nèi)存區(qū)域,用戶態(tài)和內(nèi)核態(tài)可以直接通過這個區(qū)域交換數(shù)據(jù),減少了系統(tǒng)調(diào)用上下文切換。用戶也可以一次性提交多個IO請求,減少了系統(tǒng)調(diào)用次數(shù)。
io_uring在內(nèi)核中有專門的work線程來處理用戶請求,完成IO操作,并且worker線程數(shù)量也是內(nèi)核根據(jù)cpu核心數(shù)和負(fù)載情況自己調(diào)節(jié)的。
io_uring的優(yōu)點:
- 高并發(fā),通過異步IO機制,一個線程能夠同時進行大量的IO處理,不會產(chǎn)生阻塞。
- 高性能低延遲,讀寫操作在內(nèi)核態(tài)完成,并且IO請求和IO結(jié)果都是通過共享內(nèi)存來傳遞的,減少了系統(tǒng)調(diào)用和上下文切換次數(shù)。
2. liburing的使用流程
2.1 多線程設(shè)計
- 每個線程一個io_uring–> 不用考慮同步,但是浪費資源
- 一個io_uring線程加一個線程池處理任務(wù) --> 需要考慮同步問題
- 多個線程使用一個io_uring,同樣需要考慮同步問題
2.2 流程
-
創(chuàng)建
io_uring
實例int ret = io_uring_queue_init(32, &ring, 0); // 初始化 io_uring 實例,隊列深度為 32
-
填充IO請求
sqe = io_uring_get_sqe(&ring); // 獲取一個提交隊列入口io_uring_prep_write(sqe, fd, buf, strlen(buf), 0); // 寫入文件 io_uring_prep_read(sqe, fd, buf, sizeof(buf), 0); // 異步讀取文件
-
提交IO請求
int submitted = io_uring_submit(&ring); // 提交請求到內(nèi)核
-
等待IO請求完成
int ret = io_uring_wait_cqe(&ring, &cqe); // 等待完成隊列中的一個請求完成 io_uring_cqe_seen(&ring, cqe); // 告訴 io_uring 已經(jīng)處理完該完成隊列入口
-
清理資源
io_uring_cqe_seen(&ring, cqe); // 告訴 io_uring 已經(jīng)處理完該完成隊列入口
3. proactor網(wǎng)絡(luò)模型
proactor網(wǎng)絡(luò)模型是一種異步IO事件驅(qū)動的模型,它向內(nèi)核提交IO請求,然后等待內(nèi)核完成IO操作后,再提取結(jié)果。它與reactor一樣都是高性能、高并發(fā)的網(wǎng)絡(luò)模型,與reactor的區(qū)別在于,IO事件的處理是在內(nèi)核態(tài)完成的,用戶直接獲取IO操作的結(jié)果。
Proactor 模式的關(guān)鍵思想是將 I/O 操作的處理責(zé)任交給操作系統(tǒng),應(yīng)用程序只負(fù)責(zé)發(fā)起請求和處理回調(diào)。
proactor的優(yōu)點
- 高性能的異步IO,IO操作在內(nèi)核態(tài)完成,內(nèi)核完成后將結(jié)果通知用戶,因此能夠減少系統(tǒng)調(diào)用和上下文切換,提高性能。
- 高并發(fā),和reactor一樣,都能夠用一個線程同時處理大量連接的IO請求,只不過reactor依靠的是IO多路復(fù)用機制,而proactor依賴的異步IO。
- 線程復(fù)用性,和reactor一樣,proactor也可以減少線程的切換、創(chuàng)建、銷毀的開銷,節(jié)約線程資源,程序的局部性更好,對緩存更友好。
4. proactor模式的使用場景
- 高性能、高并發(fā)、內(nèi)核5.1以上
4.1 reactor對比proactor
- IO事件處理上:
reactor在用戶態(tài)處理IO操作
,用戶需要注冊事件、等待事件發(fā)生,然后在用戶態(tài)調(diào)用IO操作;而proactor模式在內(nèi)核處理IO操作
,用戶只需提交異步IO請求,然后等待和獲取IO操作的結(jié)果,內(nèi)核態(tài)的worker線程會進行實際的IO操作。 - 性能上:由于proactor模式由內(nèi)核來負(fù)責(zé)處理IO操作,減少了系統(tǒng)調(diào)用和上下文切換次數(shù),性能較強。經(jīng)過實測,在echo回聲應(yīng)用上測試16、64、512、1024長度消息,proactor的性能平均要比epoll高10%左右。