AVt天堂网 手机版,亚洲va久久久噜噜噜久久4399,天天综合亚洲色在线精品,亚洲一级Av无码毛片久久精品

當前位置:首頁 > 科技  > 軟件

聊聊 Libuv 最近引入的 io_uring

來源: 責編: 時間:2023-10-20 10:02:31 286觀看
導讀io_uring 是 Linux 下高性能的異步 IO 框架,網(wǎng)上很多相關資料,我之前也初步分析了一下它的實現(xiàn),有興趣的可以查看 https://zhuanlan.zhihu.com/p/387620810。Libuv 中最近加入了對 io_uring 的支持,那么為什么要把它引入

t6M28資訊網(wǎng)——每日最新資訊28at.com

io_uring 是 Linux 下高性能的異步 IO 框架,網(wǎng)上很多相關資料,我之前也初步分析了一下它的實現(xiàn),有興趣的可以查看 https://zhuanlan.zhihu.com/p/387620810。t6M28資訊網(wǎng)——每日最新資訊28at.com

Libuv 中最近加入了對 io_uring 的支持,那么為什么要把它引入 Libuv 呢?因為 epoll 不支持普通文件的 Poll 能力,所以在 Libuv 中,異步文件 IO 操作需要通過線程池來實現(xiàn),具體來說就是當用戶發(fā)起一個異步文件 IO 操作時,Libuv 會把這個操作放到線程池中,當子線程處理這個任務時,會執(zhí)行一個阻塞式的系統(tǒng)調(diào)用,這個系統(tǒng)調(diào)用會引起線程阻塞,從而導致這個線程被消耗掉了,當 IO 操作完成后,子線程就會被喚醒,子線程再通過主線程去執(zhí)行用戶的回調(diào)。在 Libuv 早期的實現(xiàn)中,如果執(zhí)行比較慢的任務過多就會把線程池中的線程消耗完,從而導致執(zhí)行比較快的 IO 操作需要等待很長時間,一個例子就是 DNS 解析會阻塞文件 IO 任務。而 io_uring 可以支持普通文件 IO(當然能力不僅于此),不再需要借助線程池的能力,目前 Libuv 中部分異步文件 IO 操作已經(jīng)替換成 io_uring(需要通過環(huán)境變量開啟),下面來看看它的實現(xiàn)。t6M28資訊網(wǎng)——每日最新資訊28at.com

原生 io_uring 的使用比較復雜,通常需要借助 liburing 庫,但是 Libuv 中可能為了減少對第三方庫的依賴,實現(xiàn)上使用原生的方式。t6M28資訊網(wǎng)——每日最新資訊28at.com

io_uring 初始化t6M28資訊網(wǎng)——每日最新資訊28at.com

在 Libuv 初始化時會進行 io_uring 的初始化。t6M28資訊網(wǎng)——每日最新資訊28at.com

uv__iou_init(loop->backend_fd, &lfields->iou, 64, UV__IORING_SETUP_SQPOLL);

lfields->iou 為 io_uring 核心結(jié)構(gòu)體,UVIORING_SETUP_SQPOLL 設置內(nèi)核創(chuàng)建線程輪詢是否有任務需要處理(用戶層設置),接著看看 uviou_init。t6M28資訊網(wǎng)——每日最新資訊28at.com

static void uv__iou_init(int epollfd,struct uv__iou* iou,uint32_t entries,uint32_t flags) {struct uv__io_uring_params params;struct epoll_event e;size_t cqlen;size_t sqlen;size_t maxlen;size_t sqelen;uint32_t i;char* sq;char* sqe;int ringfd;memset(?ms, 0, sizeof(params));params.flags = flags;// UV__IORING_SETUP_SQPOLL 模式下,設置多久沒有任務提交則內(nèi)核線程進入 sleep 狀態(tài)if (flags & UV__IORING_SETUP_SQPOLL)params.sq_thread_idle = 10;  /* milliseconds /// 調(diào)用系統(tǒng)調(diào)用初始化 io_uringringfd = uv__io_uring_setup(entries, ?ms);// 映射到內(nèi)核發(fā)送 / 完成隊列的內(nèi)存,用戶層和內(nèi)核可以共同操作這個隊列sq = mmap(0,maxlen,PROT_READ | PROT_WRITE,MAP_SHARED | MAP_POPULATE,ringfd,0);  /sqe = mmap(0,sqelen,PROT_READ | PROT_WRITE,MAP_SHARED | MAP_POPULATE,ringfd,0x10000000ull);  /* IORING_OFF_SQES */memset(&e, 0, sizeof(e));e.events = POLLIN;e.data.fd = ringfd;// 注冊等待可讀事件,io_uring 中有任務完成后就會通過 epollepoll_ctl(epollfd, EPOLL_CTL_ADD, ringfd, &e);// 初始化 io_uring 結(jié)構(gòu)體iou->sqhead = (uint32_t*) (sq + params.sq_off.head);iou->sqtail = (uint32_t*) (sq + params.sq_off.tail);iou->sqmask = (uint32_t) (sq + params.sq_off.ring_mask);iou->sqarray = (uint32_t*) (sq + params.sq_off.array);iou->sqflags = (uint32_t*) (sq + params.sq_off.flags);iou->cqhead = (uint32_t*) (sq + params.cq_off.head);iou->cqtail = (uint32_t*) (sq + params.cq_off.tail);iou->cqmask = (uint32_t) (sq + params.cq_off.ring_mask);iou->sq = sq;iou->cqe = sq + params.cq_off.cqes;iou->sqe = sqe;iou->sqlen = sqlen;iou->cqlen = cqlen;iou->maxlen = maxlen;iou->sqelen = sqelen;iou->ringfd = ringfd;iou->in_flight = 0;iou->flags = 0;}

uv__iou_init 完成了 io_uring 的初始化,并且把 io_uring 對應的 fd 注冊到 epoll,當 io_uring 有任務完成時,就可以通過 epoll 感知到。接著就可以使用 io_uring 了。t6M28資訊網(wǎng)——每日最新資訊28at.com

提交異步任務

下面看一個異步文件 IO 的操作。t6M28資訊網(wǎng)——每日最新資訊28at.com

int uv_fs_open(uv_loop_t* loop,uv_fs_t* req,const char* path,int flags,int mode,uv_fs_cb cb) {INIT(OPEN);PATH;req->flags = flags;req->mode = mode;if (cb != NULL)if (uv__iou_fs_open(loop, req))return 0;POST;}

uv_fs_open 可以以異步的方式打開一個文件,之前時通過線程池實現(xiàn)的,加入 io_uring 后,就會多了一層攔截,來看看 uv__iou_fs_open。t6M28資訊網(wǎng)——每日最新資訊28at.com

t6M28資訊網(wǎng)——每日最新資訊28at.com

int uv__iou_fs_open(uv_loop_t* loop, uv_fs_t* req) {struct uv__io_uring_sqe* sqe;struct uv__iou* iou;// 獲取 io_uring 結(jié)構(gòu)體iou = &uv__get_internal_fields(loop)->iou;// 獲取一個任務節(jié)點,任務節(jié)點會和 req 互相關聯(lián),回調(diào)時會用到sqe = uv__iou_get_sqe(iou, loop, req);// 設置操作上下文sqe->addr = (uintptr_t) req->path;sqe->fd = AT_FDCWD;sqe->len = req->mode;// 設置操作類型sqe->opcode = UV__IORING_OP_OPENAT;sqe->open_flags = req->flags | O_CLOEXEC;// 提交任務uv__iou_submit(iou);return 1;}

uviou_fs_open 中有兩個核心邏輯 uviou_get_sqe 和 uviou_submit,首先來看 uviou_get_sqe。t6M28資訊網(wǎng)——每日最新資訊28at.com

t6M28資訊網(wǎng)——每日最新資訊28at.com

static struct uv__io_uring_sqe* uv__iou_get_sqe(struct uv__iou* iou,uv_loop_t* loop,uv_fs_t* req) {struct uv__io_uring_sqe* sqe;uint32_t head;uint32_t tail;uint32_t mask;uint32_t slot;if (iou->ringfd == -1)return NULL;head = atomic_load_explicit((_Atomic uint32_t*) iou->sqhead,memory_order_acquire);tail = *iou->sqtail;mask = iou->sqmask;slot = tail & mask;sqe = iou->sqe;// 從請求隊列中獲取一個節(jié)點sqe = &sqe[slot];memset(sqe, 0, sizeof(*sqe));// 任務節(jié)點關聯(lián)到 req,回調(diào)時需要使用sqe->user_data = (uintptr_t) req;req->work_req.loop = loop;req->work_req.work = NULL;req->work_req.done = NULL;uv__queue_init(&req->work_req.wq);uv__req_register(loop, req);iou->in_flight++;return sqe;}

uviou_get_sqe 主要是從任務隊列中獲取一個空閑節(jié)點并關聯(lián)上請求上下文結(jié)構(gòu)體,uviou_get_sqe 的調(diào)用方需要設置操作上下文,比如操作類型,操作的 fd 等。通過 uviou_get_sqe 獲取任務節(jié)點并設置了操作上下文后,這個任務就會自動被操作系統(tǒng)感知。因為 Libuv 是使用了 UVIORING_SETUP_SQPOLL 模式,所以還需要判斷這時候內(nèi)核輪訓線程是否處于睡眠狀態(tài),這就是 uv__iou_submit 的邏輯。t6M28資訊網(wǎng)——每日最新資訊28at.com

static void uv__iou_submit(struct uv__iou* iou) {uint32_t flags;atomic_store_explicit((_Atomic uint32_t*) iou->sqtail,*iou->sqtail + 1,memory_order_release);flags = atomic_load_explicit((_Atomic uint32_t*) iou->sqflags,memory_order_acquire);// 判斷內(nèi)核線程是否處于睡眠狀態(tài)if (flags & UV__IORING_SQ_NEED_WAKEUP)// 喚醒內(nèi)核線程,說明有任務需要處理if (uv__io_uring_enter(iou->ringfd, 0, 0, UV__IORING_ENTER_SQ_WAKEUP))if (errno != EOWNERDEAD)  /* Kernel bug. Harmless, ignore. /perror("libuv: io_uring_enter(wakeup)");  /

這樣就完成了任務的提交。t6M28資訊網(wǎng)——每日最新資訊28at.com

任務完成

任務完成后,io_uring 對應的 fd 就會變成可讀,從而 epoll 就會感知到,來看看 epoll 的處理。下面是 epoll 處理就緒 fd 時的一段邏輯。t6M28資訊網(wǎng)——每日最新資訊28at.com

t6M28資訊網(wǎng)——每日最新資訊28at.com

if(fd == iou->ringfd) {uv__poll_io_uring(loop, iou);have_iou_events = 1;continue;}

如果是 io_uring 的 fd 可讀,則執(zhí)行 uv__poll_io_uring。t6M28資訊網(wǎng)——每日最新資訊28at.com

t6M28資訊網(wǎng)——每日最新資訊28at.com

static void uv__poll_io_uring(uv_loop_t* loop, struct uv__iou* iou) {struct uv__io_uring_cqe* cqe;struct uv__io_uring_cqe* e;uv_fs_t* req;uint32_t head;uint32_t tail;uint32_t mask;uint32_t i;uint32_t flags;int nevents;int rc;// 完成隊列頭/尾節(jié)點head = iou->cqhead;tail = atomic_load_explicit((_Atomic uint32_t) iou->cqtail,memory_order_acquire);mask = iou->cqmask;cqe = iou->cqe;nevents = 0;// 遍歷完成隊列for (i = head; i != tail; i++) {e = &cqe[i & mask];// 拿到操作關聯(lián)的請求結(jié)構(gòu)體req = (uv_fs_t*) (uintptr_t) e->user_data;uv__req_unregister(loop, req);iou->in_flight--;// 操作返回值,表示操作是否成功req->result = e->res;// 執(zhí)行回調(diào)req->cb(req);}

uv__poll_io_uring 的邏輯很簡單,就是遍歷完成隊列,然后拿到對應的請求上下文結(jié)構(gòu)體,最后執(zhí)行它的回調(diào)。t6M28資訊網(wǎng)——每日最新資訊28at.com

現(xiàn)代軟件中大多數(shù)使用的 IO 模型是 epoll,隨著 io_uring 的發(fā)展和成熟,io_uring 將會出現(xiàn)在更多的軟件中,之前我也體驗了一下 io_uring,有興趣的可以體驗下 https://github.com/theanarkh/nodejs_io_uring。t6M28資訊網(wǎng)——每日最新資訊28at.com

本文鏈接:http://www.tebozhan.com/showinfo-26-14326-0.html聊聊 Libuv 最近引入的 io_uring

聲明:本網(wǎng)頁內(nèi)容旨在傳播知識,若有侵權(quán)等問題請及時與本網(wǎng)聯(lián)系,我們將在第一時間刪除處理。郵件:2376512515@qq.com

上一篇: Kubernetes中的優(yōu)雅關閉和零停機時間部署

下一篇: 業(yè)務痛點如此不同,為什么解決辦法卻那么一致?

標簽:
  • 熱門焦點
  • 直屏旗艦來了 iQOO 12和K70 Pro同臺競技

    旗艦機基本上使用的都是雙曲面屏幕,這就讓很多喜歡直屏的愛好者在苦等一款直屏旗艦,這次,你們等到了。據(jù)博主數(shù)碼閑聊站帶來的最新爆料稱,Redmi下代旗艦K70 Pro和iQOO 12兩款手
  • 2023 年的 Node.js 生態(tài)系統(tǒng)

    隨著技術(shù)的不斷演進和創(chuàng)新,Node.js 在 2023 年達到了一個新的高度。Node.js 擁有一個龐大的生態(tài)系統(tǒng),可以幫助開發(fā)人員更快地實現(xiàn)復雜的應用。本文就來看看 Node.js 最新的生
  • 一年經(jīng)驗在二線城市面試后端的經(jīng)驗分享

    忠告這篇文章只適合2年內(nèi)工作經(jīng)驗、甚至沒有工作經(jīng)驗的朋友閱讀。如果你是2年以上工作經(jīng)驗,請果斷劃走,對你沒啥幫助~主人公這篇文章內(nèi)容來自 「升職加薪」星球星友 的投稿,坐
  • 在線圖片編輯器,支持PSD解析、AI摳圖等

    自從我上次分享一個人開發(fā)仿造稿定設計的圖片編輯器到現(xiàn)在,不知不覺已過去一年時間了,期間我經(jīng)歷了裁員失業(yè)、面試找工作碰壁,寒冬下一直沒有很好地履行計劃.....這些就放在日
  • 深度探索 Elasticsearch 8.X:function_score 參數(shù)解讀與實戰(zhàn)案例分析

    在 Elasticsearch 中,function_score 可以讓我們在查詢的同時對搜索結(jié)果進行自定義評分。function_score 提供了一系列的參數(shù)和函數(shù)讓我們可以根據(jù)需求靈活地進行設置。近期
  • 中國家電海外掘金正當時|出海專題

    作者|吳南南編輯|胡展嘉運營|陳佳慧出品|零態(tài)LT(ID:LingTai_LT)2023年,出海市場戰(zhàn)況空前,中國創(chuàng)業(yè)者在海外紛紛摩拳擦掌,以期能夠把中國的商業(yè)模式、創(chuàng)業(yè)理念、戰(zhàn)略打法輸出海外,他們依
  • 重估百度丨大模型,能撐起百度的“今天”嗎?

    自象限原創(chuàng) 作者|程心 羅輯2023年之前,對于自己的“今天”,百度也很迷茫。“新業(yè)務到 2022 年底還是 0,希望 2023 年出來一個 1。”這是2022年底,李彥宏
  • 網(wǎng)傳小米汽車開始篩選交付中心 建筑面積不低于3000平方米

    7月7日消息,近日有微博網(wǎng)友@長三角行健者爆料稱,據(jù)經(jīng)銷商集團反饋,小米汽車目前已經(jīng)開始了交付中心的篩選工作,要求候選場地至少有120個車位,建筑不能低
  • 2納米決戰(zhàn)2025

    集微網(wǎng)報道 從三強爭霸到四雄逐鹿,2nm的廝殺聲已然隱約傳來。無論是老牌勁旅臺積電、三星,還是誓言重回先進制程領先地位的英特爾,甚至初成立不久的新
Top