NNG/NanoMsg进程线程间通讯库
NNG/nanomsg?是最近項目上使用到的一個通信庫,用來實現進程間過程調用和線程間通信,很是方便。
NNG 是 nanomsg 的繼任版本,而 nanomsg 則是流行的?ZMQ?的 C 重寫版。
NNG 將通信使用的協議和傳輸分離,同一個協議可以工作在不同的傳輸層上,類似與 TCP/IP 的應用層和傳輸層的分層,同時接口上屏蔽了底層細節,統一用字符串 URL 來描述傳輸模式。這樣當使用場景修改時,可以通過簡單修改 URL 來實現適應,極具靈活性。
同時如 NNG 描述所言 “light-weight brokerless messaging”,NNG 中的通信各方是不需要第三方程序介入的,這與 MQTT/Redis 通信需要服務器不同。這樣很適合作為通信庫來使用而沒有其他依賴。
NNG 支持的通信協議主要有以下幾種:
- PAIR 一對一雙向通信。
- PIPELINE(PUSH/PULL) 單向通信,類似與生產者消費者模型的消息隊列。
- PUB/SUB 單向廣播。
- REQ/REP 請求-應答模式,類似與 RPC 模式。
- BUS 網狀連接通信,每個加入節點都可以發送/接受廣播消息。
- SURVEY 用于多節點表決或者服務發現。
NNG 支持的傳輸模式主要有以下三種常用,其他還有tcp附加tls 1.2加密的tls傳輸和基于WebSocket的ws傳輸:
- inproc 進程內線程間傳輸
- ipc 主機內進程間傳輸
- tcp 網絡內主機間傳輸
通信協議里除了 PAIR 之外,基本都是一對多的通信模式,這點需要注意,以 PIPELINE 和 PUB/SUB 為例:
基于以上,多個程序是沒辦法共用一個 PUB/SUB 通道來廣播數據的,這與 ROS 里的 topic 和 LCM 中的 channel 模式不同。如果要實現類似功能,則可以使用 PIPELINE + PUB/SUB 來處理:
- 獨立一個話題發布的程序,擁有一個 PULL 和 PUB。
- PULL 約定一個 URL,所有需要發布該話題的程序都 PUSH 數據到該 URL 上。
- PUB 約定一個 URL,所有需要獲取該話題的程序都 SUB 到該 URL 上。
- 程序內部循環將 PULL 讀取的數據發送到 PUB 上。
以上則可以模擬出 ROS topic 數據合并 或者 LCM 中 channel 的類似功能。
整體上看,NNG 的 API 很簡約,主要是 4 個,open/recv/send/close,open 根據協議不同使用的函數會不同。配置則是 setopt/getopt,與 UNIX API 類似。API 中沒有上下文環境(context-less)依賴,只需要一個 nng_socket,這種設計和實現方法值得去學習一下(初步揣測應該是使用指針值作為handle,如果要強制編譯器做類型檢測,則會套上一層 struct,如?typedef struct { _nng_xxx_socket * p } nng_socket;)。
NNG 協議基本上囊括了常見的通信需求,一些特殊的需求,也可以通過組合協議來實現,比如上面的模擬 ROS topic 或者 LCM channel 的方法。這樣一來,如果在程序中使用 NNG,不管是多進程,還是多線程,通過設計,可以進一步增強模塊化,同時不乏靈活性。如果環境變化,程序不管是由多進程改成多線程,還是由多線程改成多主機,都很容易實現。
常見模塊/進程/線程間通信,可以依據具體需求來使用 PIPELINE(消息隊列) 還是 REQ/REP(過程調用),而不是鎖+全局變量,每個模塊單元只需要做單一相關的具體事務,無需知曉全局狀態。
總結
以上是生活随笔為你收集整理的NNG/NanoMsg进程线程间通讯库的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: HTML学习---中文网页编码声明
- 下一篇: 总结linux FHS结构