CERL2 系列2 網路程式設計該用同步還是非同步?

2021-05-18 07:57:11 字數 1139 閱讀 4878

在c/c++中,libevent、boost asio 這兩個網路庫都採用非同步程式設計模型,當io完成事件發生時,呼叫乙個**函式處理它。這種程式設計模型有很好的io吞吐量。但是付出的代價也很大:

醜陋的**。應用程式邏輯被乙個個**函式切割得支離破碎。

複雜的記憶體管理。乙個不小心,就有可能出現**函式執行的時候,相應的記憶體已經被釋放。

除錯困難。由於函式被切割,debug的時候,**執行順序不能很好地保持思維的連貫。

erlang 語言很好地解決了這個問題。正是它引入了「輕量級程序」這個解決方案。這個解決方案的觀念很質樸:單個程序採用同步呼叫,而用足夠多的程序來使得io並行化,提高io吞吐量。

其實,類似的觀念並不是erlang首先提出的。我們想想作業系統。單個程序(或執行緒)採用同步io(read/write)。要同時做多個io操作?建立新程序(或執行緒)來做這件事情。

所以,erlang 真正的創舉在於「程序」的「輕量級」。只有程序輕量級了,才可以無所顧忌地建立程序。而io並行化才得以實施。

所以,我推崇 erlang 語言,最根本的一點,在於它告訴大家,高效能的網路伺服器的**也可以是很簡單、很優雅的。

cerl2 繼承了 erlang 或者 作業系統的這個哲學。我們舉個例子:

假設我們已經實現了乙個向單個伺服器的rpc**:

void call(result& result, const host& host, const request& req);

此為向 host 傳送 req 請求,返回 result。

如果我們希望同時向多個伺服器傳送同乙個請求,這個在網路程式設計中稱為 multi_call。原型如下:

void multi_call(result results, const host hosts, size_t n, const request& req);

在 cerl2 中要實現該功能,你無須修改call的**。簡單用 n 個纖程分別來做乙個單獨的 call 即可。

所以,cerl2 程式設計是很簡單的,因為你一直以來就用這種方式在思考,不是嗎?

最後我們重複一下 cerl2 程式設計哲學中最重要的原則:

在 cerl2 中,只有同步呼叫。要想使 io 並行,用多個纖程(fiber)就好。

CERL2 系列6 SDL,面向資料流的網路協議

在 cerl2 系列5 sdl與我對網路協議的思考 一文中,儘管我對 sdl 的來龍去脈做了介紹,但是我發現還是遺漏了非常重要的內容。朋友們可能會問,sdl看起來不就是乙個普通的idl 介面描述語言 嗎,為什麼不直接沿用乙個現成的標準呢?很多時候,看似相似的東西卻會是貌似神不是。正是因為我覺得idl...

Linux網路程式設計 (2)網路程式設計基礎

一 ip位址 1 ip的概念 internet protocol 網路之間互連的協議 也就是為計算機網路相互連線進行通訊而設計的協議。在 網際網路中,它是能使連線到網上的所有計算機網路實現相互通訊的一套規則,規定了 計算機在網際網路上進行通訊時應當遵守的規則。任何廠家生產的計算機系統,只要遵守ip協...

python 2 網路程式設計

訪問某網域名稱的過程 以www.baidu.com 為例 1.先要知道預設閘道器的mac 1.1 使用arp獲取預設閘道器的mac位址 1.2.組織資料傳送給預設閘道器 ip為dns伺服器的ip,但是mac位址是預設閘道器的mac位址 1.3.預設閘道器擁有 資料的能力,把資料 給路由器 1.4.路...