最美情侣中文字幕电影,在线麻豆精品传媒,在线网站高清黄,久久黄色视频

歡迎光臨散文網(wǎng) 會(huì)員登陸 & 注冊

boost asio 的一些問題

2023-02-23 16:19 作者:Meriex  | 我要投稿


周末用 boost asio 配合 beast::http 寫了一個(gè)小的異步 https 客戶端 demo,可以通過 cookie 從 bilibili 服務(wù)器獲取本機(jī)已登陸用戶的 id 還有所佩戴的徽章(只拿了一些簡單的信息,比如徽章名字還有等級),我自己的構(gòu)思中這可以作為一些粉絲服務(wù)的前置信息。(比如大家都是 Asaki 的粉絲然后就可以直接轉(zhuǎn)到一個(gè)聊天室這種)


那在實(shí)現(xiàn)的過程中就發(fā)現(xiàn)不可避免的碰到了回調(diào)地獄的問題(因?yàn)樽约簩f(xié)程其實(shí)了解不多所以也沒有用相關(guān)特性),這里做一個(gè)小的總結(jié):


首先我們正?;蛘哒f大部分時(shí)間寫代碼都是以一種同步的方式進(jìn)行的,比如我現(xiàn)在寫 cephfs 的代碼, client 要給 mds 發(fā)送一條消息請求 open 一個(gè)文件,這個(gè)流程是怎么樣的,他一定是三步走:

  1. make_request 創(chuàng)建一條 open 請求

  2. 向 mds 發(fā)送這個(gè)請求并等待 mds 處理

  3. 處理 mds 回復(fù)并向 kernel 返回結(jié)果

在這個(gè)過程中我們說只要 mds 沒有處理完成這個(gè) open 請求,那么 client 或者說 client 的這個(gè)線程就一定會(huì)阻塞在 wait() 處。什么,你想處理多個(gè)請求?那么請使用多個(gè)線程來處理這些請求,同樣的,每個(gè)線程都會(huì)阻塞在各自的 wait() 處等待 mds 返回。


使用多線程技術(shù)確實(shí)可以減少 cpu 算力出現(xiàn)空置的情況,但緊接著 c10k 問題的普及讓人們發(fā)現(xiàn) cpu 對大量線程的調(diào)度實(shí)際上是對 cpu 性能的致命浪費(fèi),這嚴(yán)重影響了服務(wù)器的絕對性能,因此以 nginx 為代表的異步服務(wù)器設(shè)計(jì)出現(xiàn)并成為主流,同時(shí)異步編程方式也為大家所熟知。


如果我們使用異步的方式去改寫剛才 open 文件的過程,就會(huì)像下面這樣:

  1. make_request 創(chuàng)建一條 open 請求

  2. 向事件隊(duì)列提交一個(gè)異步操作(向 mds 發(fā)送這個(gè)請求)并立即返回

  3. make_request 創(chuàng)建第二條請求

  4. 向事件隊(duì)列提交一個(gè)異步操作并立即返回

  5. 啟動(dòng)事件循環(huán)向 mds 發(fā)送請求

  6. mds 返回第一個(gè)請求, client 通過提前設(shè)置的回調(diào)處理并返回

  7. mds 返回第二個(gè)請求, client 通過提前設(shè)置的回調(diào)處理并返回

以上的所有過程都是在同個(gè)線程中完成,因此避免了線程切換,提高了 cpu 利用率,唯一的阻塞點(diǎn)在啟動(dòng)事件循環(huán)(因?yàn)樾枰却祷兀?/p>


在 asio 中,提交異步操作就是通過 async_xxx 函數(shù)完成,而執(zhí)行異步操作以及監(jiān)聽事件循環(huán)就是通過 io_context.run() 觸發(fā)


但是這樣就不可避免的遇到一個(gè)問題,如果一個(gè)操作有多個(gè)步驟并且多個(gè)步驟都依賴上一步完成,那么我們就必須在上一步的回調(diào)中執(zhí)行下一步操作,比如我要和?api.bilibili.com?建立一個(gè) tls 連接:

  1. 提交一個(gè)解析域名的異步操作 async_resolve

  2. 設(shè)置 async_resolve 的回調(diào)函數(shù)為提交一個(gè)連接到 server 的異步操作 async_connect

  3. 設(shè)置 async_connect 的回調(diào)函數(shù)為提交一個(gè)建立 tls 連接的異步操作 async_handshake

  4. 設(shè)置 async_handshake 的回調(diào)函數(shù)將 session 狀態(tài)設(shè)為 ready

  5. 通過 io_context.run() 開始事件循環(huán)

  6. async_resolve 返回,通過回調(diào)函數(shù)調(diào)用 async_connect

  7. async_connect 返回,通過回調(diào)函數(shù)調(diào)用 async_handshake

  8. async_handshake 返回,通過回調(diào)函數(shù)將 session 狀態(tài)設(shè)為 ready


簡化的代碼大概類似這樣:

這種鏈?zhǔn)降恼{(diào)用方式導(dǎo)致我們很難對代碼進(jìn)行拆分和抽象,這也是“回調(diào)地獄”的由來,你的所有操作只能通過一條遞歸的線來進(jìn)行,除非通過多線程配合 promise 和 future 還有可能解決,單線程中我感覺無解。


那解決辦法的話之前其實(shí)也提到了,通過協(xié)程來實(shí)現(xiàn),也就是??吹降摹耙酝椒绞綄懏惒酱a”


所以說協(xié)程還是繞不過去的坎啊,哎,學(xué),現(xiàn)在就學(xué)。


boost asio 的一些問題的評論 (共 條)

分享到微博請遵守國家法律
双峰县| 海淀区| 孟村| 稻城县| 杭锦旗| 镇远县| 乃东县| 北川| 融水| 巴青县| 武宁县| 正阳县| 绥德县| 南部县| 黄骅市| 大英县| 潼关县| 韶关市| 罗江县| 莆田市| 中西区| 德保县| 鸡泽县| 庆阳市| 正蓝旗| 甘泉县| 威宁| 庄浪县| 常熟市| 云浮市| 文化| 循化| 永川市| 庆城县| 旅游| 内江市| 廉江市| 吉安市| 昭苏县| 祁东县| 天全县|