詳解node中進程通訊的幾種實作方式
node進程間如何通訊?以下這篇文章帶大家了解node進程的通信方式,以及在node中如何實現這些方式的通信,希望對大家有所幫助!
通信其實涵蓋開發的各個層面,常見的有客戶端和服務端透過各種通訊協定進行通信,RPC通信,開發過程中各個模組之間的相互通信,electron主程序和渲染進程之間的通信等等;
本文主要是嘗試總結下nodejs(單線程,多線程,多進程)通信的方式,使用場景,實現等。
通訊的實作方式
一般進程通訊的實作方式如下:
1、Shared Memory(記憶體共享);
2、Socket(套接字);
3、管道(非命名管道Pipe, 命名管道FIFO);
#4、Signal(訊號);
#5 、Message queue(訊息佇列);
下面我們看下在node中如何實作這些方式的通訊
一、Shared Memory(記憶體共享)
單機下(客戶端內單線程,單一進程裡多線程,單一伺服器內多進程),透過記憶體共享實現通訊的方式最常見。
Shared Memory(記憶體共享)-單線程
從作業系統層面來看,進程內所有執行緒記憶體都是共享的,但前提是需要知道記憶體的訪問地址。
但從語言層面(node或v8的實作層面),我們並沒有直接接觸記憶體的管理,而是間接從v8提供的語法/api進行記憶體運算。 v8提供三種方式給我們共享記憶體(也許叫共享變數更恰當):全域變數, 局部變數, 共享傳參(call by sharing) ;
v8在執行程式碼之前會先將程式碼透過Estree規範轉換為抽象語法樹後再進行解釋編譯執行,在抽象語法樹中(關於抽象語法樹可查看我另外一篇文章)是有scope的,而記憶體讀取是透過標誌符號(變數命名)逐級往上回溯查找。所以如果你需要在兩個方法之間共享某個內存,可以在他們共同的作用域下進行創建。
Shared Memory(記憶體共享)-多執行緒
在客戶端環境或node環境,我們都可以實現多執行緒,兩者方式也類似(node通過worker_threads實現,瀏覽器透過Worker實現)。這裡的記憶體共享主要是藉由記憶體操作的api(SharedArrayBuffer)實現的。先看下瀏覽器實作的例子:
// 主线程 const buffer = new SharedArrayBuffer(1024) const typedArr = new Int16Array(buffer) const newWorker = new Worker('./worker.js') typedArr[0] = 20 newWorker.postMessage(buffer) newWorker.onmessage= (data) => { console.group('[the main thread]'); console.log('Data received from the main thread: %i', typedArr[0]); console.groupEnd(); } // 子线程 addEventListener('message', ({ data }) => { const arr = new Int16Array(data) console.group('[the worker thread]') console.log('Data received from the main thread: %i', arr[0]) console.groupEnd() arr[0] = 18 postMessage('Updated') }) // 结果 [the worker thread] Data received from the main thread: 20 [the main thread] Data received from the main thread: 18
Shared Memory(記憶體共享)-多進程
因為進程啟動後記憶體是無法互相讀取的(系統層面的限制),進程之間的記憶體共享實際上是透過新開闢一段shared memory實現的。但node暫時沒有支援shared memory,只能透過低階語言來實現,例如: c 實現的 shared-memory-disruptor addon插件(另外文章介紹)。
二、Socket(套接字)
Socket 分兩種實作:
1、TCP Socket;
2、UNIX Domain Socket;
兩者的主要差異如下:
TCP Socket适用于单机,C/S架构等.但UNIX Domain Socket只适用于单机。 UNIX Domain Socket不需要经过一系列的网络中转(协议,分包,校验等等),性能更高,稳定性更好。
TCP Socket
概念: TCP Socket是應用層與TCP/IP協定族通訊的中間抽象層,是一種作業系統提供的進程間通訊機制;
TCP Socket通訊應該是我們日常開發(C/S架構)中最常見的通訊方式之一,在我們日常開發中最常見的就是各種應用層協定(http ,websocket,rpc,ftp等)的使用,node中http模組也是基於net模組實現的。
註:其實UDP也屬於TCP分層(並不是嚴格的指TCP通信,而是網路通訊層中的TCP/IP層),node有提供'dgram'模組來實現,但在實際應用中沒有接觸過,所以不進行了解。
net
在node中,TCP Socket是由net模組實現的,net模組主要提供了以下功能:
1、上層的IPC支援(實際上是管道通訊的實現,後面管道通訊再詳細說明);
2、net.Server類別;
// 服务端通过net.createServer创建服务,会返回net.Server对象,可以通过返回值进行各种事件监听,端口监听 const net = require('net') net.createServer((server => { server.end(`hello world!\n`) })).listen(3302, () => { console.log(`running ...`) })
3、net.Socket類別;
const net = require('net') const socket = net.createConnection({port: 3302}) socket.on('data', data => { console.log(data.toString()) })
UNIX Domain Socket
UNIX Domain Socket是透過建立一個檔案描述符,不同進程之間的通訊透過讀寫這個檔案描述符進行通訊(可以分為建立進程和其他進程,其他進程之間的相互通訊可以透過創建進程作為中轉)。 e.g.
// 创建进程 const net = require('net') const unixSocketServer = net.createServer(server => { server.on('data', data => { console.log(`receive data: ${data}`) }) }) unixSocketServer.listen('/tmp/test', () => { console.log('listening...') }) // 其他进程 const net = require('net') const socket = net.createConnection({path: '/tmp/test'}) socket.on('data', data => { console.log(data.toString()) }) socket.write('my name is vb') // 输出结果 listening... receive data: my name is vb
三、管道
管道通訊分兩種,非命名管道和命名管道。
非命名管道的實作方式和UNIX Domain Socket一樣,都是透過建立檔案描述符進行通訊。
命名管道是透過固定的檔案描述符進行通訊:
"\\\\.\\pipe\\" + PIPE_NAME;
源码可参考stackoverflow(https://stackoverflow.com/questions/11750041/how-to-create-a-named-pipe-in-node-js)
目前理解的管道通信和UNIX Domain Socket实现基本一致,只是管道通信规范了读写权限,半双工通信,UNIX Domain Socket更加自由一些。
四、Signal(信号)
Signal是操作系统在终止进程前给进程发送的信号。在node中可以通过process.kill(pid, signal)/child_process.kill(pid, signal)接口实现,e.g.
// 要被终止的http守护进程 const Koa = require('koa') const app = new Koa() app.listen(3004, () => { console.log(`process pid is : ${process.pid}`) // process pid is : 75208 }) // 操作进程 process.kill(75208, 'SIGHUP') // 'SIGHUP'是一般结束进程的信号,还有更多其他的信号参考 [标识](https://blog.csdn.net/houjixin/article/details/71430489)
但这里的前提是你需要获取到被终止的进程pid,更多pid的内容可阅读我之前关于进程的文章。
五、Message queue(消息队列)
一开始我以为是redis,各种MQ之类的基于TCP的消息队列。但其实是操作系统内的消息队列,node暂时没有提供相关的上层接口,需要更底层实现,e.g. svmq
更多node相关知识,请访问:nodejs 教程!!
以上是詳解node中進程通訊的幾種實作方式的詳細內容。更多資訊請關注PHP中文網其他相關文章!

熱AI工具

Undresser.AI Undress
人工智慧驅動的應用程序,用於創建逼真的裸體照片

AI Clothes Remover
用於從照片中去除衣服的線上人工智慧工具。

Undress AI Tool
免費脫衣圖片

Clothoff.io
AI脫衣器

AI Hentai Generator
免費產生 AI 無盡。

熱門文章

熱工具

記事本++7.3.1
好用且免費的程式碼編輯器

SublimeText3漢化版
中文版,非常好用

禪工作室 13.0.1
強大的PHP整合開發環境

Dreamweaver CS6
視覺化網頁開發工具

SublimeText3 Mac版
神級程式碼編輯軟體(SublimeText3)

熱門話題

nvm刪除node的方法:1、下載「nvm-setup.zip」並將其安裝在C碟;2、設定環境變量,並透過「nvm -v」指令查看版本號;3、使用「nvm install」指令安裝node;4、透過「nvm uninstall」指令刪除已安裝的node即可。

怎麼處理文件上傳?以下這篇文章為大家介紹一下node專案中如何使用express來處理文件的上傳,希望對大家有幫助!

這篇文章跟大家分享Node的進程管理工具“pm2”,聊聊為什麼需要pm2、安裝和使用pm2的方法,希望對大家有幫助!

PiNetwork節點詳解及安裝指南本文將詳細介紹PiNetwork生態系統中的關鍵角色——Pi節點,並提供安裝和配置的完整步驟。 Pi節點在PiNetwork區塊鏈測試網推出後,成為眾多先鋒積極參與測試的重要環節,為即將到來的主網發布做準備。如果您還不了解PiNetwork,請參考Pi幣是什麼?上市價格多少? Pi用途、挖礦及安全性分析。什麼是PiNetwork? PiNetwork項目始於2019年,擁有其專屬加密貨幣Pi幣。該項目旨在創建一個人人可參與

如何用pkg打包nodejs可執行檔?以下這篇文章跟大家介紹一下使用pkg將Node專案打包為執行檔的方法,希望對大家有幫助!

npm node gyp失敗是因為“node-gyp.js”跟“Node.js”版本不匹配,其解決辦法:1、透過“npm cache clean -f”清除node快取;2、透過“npm install -g n”安裝n模組;3、透過「n v12.21.0」指令安裝「node v12.21.0」版本即可。

身份驗證是任何網路應用程式中最重要的部分之一。本教程討論基於令牌的身份驗證系統以及它們與傳統登入系統的差異。在本教程結束時,您將看到一個用Angular和Node.js編寫的完整工作演示。傳統身份驗證系統在繼續基於令牌的身份驗證系統之前,讓我們先來看看傳統的身份驗證系統。使用者在登入表單中提供使用者名稱和密碼,然後點擊登入。發出請求後,透過查詢資料庫在後端驗證使用者。如果請求有效,則使用從資料庫中獲取的使用者資訊建立會話,然後在回應頭中傳回會話訊息,以便將會話ID儲存在瀏覽器中。提供用於存取應用程式中受

什麼是單一登入系統?用nodejs怎麼實作?以下這篇文章為大家介紹一下使用node實作單一登入系統的方法,希望對大家有幫助!
