KnotenWie kommuniziere ich zwischen Prozessen? Der folgende Artikel wird Ihnen helfen, die Kommunikationsmethoden von Node-Prozessen zu verstehen und diese Kommunikationsmethoden in Node zu implementieren. Ich hoffe, er wird Ihnen hilfreich sein!
Die Kommunikation umfasst tatsächlich alle Entwicklungsebenen, darunter die Kommunikation zwischen Client und Server, die RPC-Kommunikation, die gegenseitige Kommunikation zwischen verschiedenen Modulen während des Entwicklungsprozesses und die Kommunikation zwischen dem Hauptelektronenprozess und dem Rendering-Prozess zwischen Knoten usw.;
Dieser Artikel versucht hauptsächlich, die Kommunikationsmethoden, Verwendungsszenarien, Implementierung usw. von nodejs (Single-Threaded, Multi-Threaded, Multi-Process) zusammenzufassen.
Shared Memory (Speicherfreigabe) – einzelner Thread
Auf Betriebssystemebene wird der gesamte Thread-Speicher im Prozess gemeinsam genutzt, Voraussetzung ist jedoch, dass die Zugriffsadresse des Speichers bekannt sein muss. Aber auf der Sprachebene (Knoten- oder v8-Implementierungsebene) berühren wir die Speicherverwaltung nicht direkt, sondern führen indirekt Speicheroperationen über die von v8 bereitgestellte Syntax/API aus. v8 bietet uns drei Möglichkeiten, den Speicher zu teilen (vielleicht sollte man ihn besser als gemeinsam genutzte Variablen bezeichnen):globale Variablen
,Gemeinsamer Speicher (Speicherfreigabe) – Multithreading In entweder der Client-Umgebung oder der Knotenumgebung können wir Multithreading implementieren, und die beiden Methoden sind ähnlich (Knoten wird über worker_threads implementiert und die Browser wird durch Worker implementiert). Die gemeinsame Nutzung des Speichers wird hier hauptsächlich mit Hilfe der Speicheroperations-API (SharedArrayBuffer) erreicht. Schauen wir uns zunächst ein Beispiel für die Browser-Implementierung an:
// 主线程 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
Gemeinsamer Speicher (Speicherfreigabe) – Multiprozess
Hinweis: Tatsächlich gehört UDP auch zur TCP-Schicht (bezieht sich nicht ausschließlich auf die TCP-Kommunikation, sondern die TCP/IP-Schicht in der Netzwerkkommunikationsschicht stellt das Modul „dgram“ zur Verfügung, um es zu implementieren, aber es gibt keins). Kontakt in tatsächlichen Anwendungen bestanden, daher kein weiteres Verständnis.
net
Im Knoten wird TCP Socket durch das Netzmodul implementiert. Das Netzmodul bietet hauptsächlich die folgenden Funktionen:
TCP Socket适用于单机,C/S架构等.但UNIX Domain Socket只适用于单机。 UNIX Domain Socket不需要经过一系列的网络中转(协议,分包,校验等等),性能更高,稳定性更好。
// 服务端通过net.createServer创建服务,会返回net.Server对象,可以通过返回值进行各种事件监听,端口监听 const net = require('net') net.createServer((server => { server.end(`hello world!\n`) })).listen(3302, () => { console.log(`running ...`) })
UNIX Domain Socket
UNIX Domain Socket erstellt einen Dateideskriptor, und die Kommunikation zwischen verschiedenen Prozessen erfolgt durch Lesen und Schreiben Sie diesen Dateideskriptor für die Kommunikation (kann in den Erstellungsprozess und andere Prozesse unterteilt werden, und die gegenseitige Kommunikation zwischen anderen Prozessen kann durch den Erstellungsprozess als Transit erfolgen). z.B.const net = require('net') const socket = net.createConnection({port: 3302}) socket.on('data', data => { console.log(data.toString()) })
Unbenannte Pipes werden auf die gleiche Weise wie UNIX-Domänen-Sockets implementiert und kommunizieren durch die Erstellung von Dateideskriptoren.
Named Pipes kommunizieren über feste Dateideskriptoren:"\\\\.\\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是操作系统在终止进程前给进程发送的信号。在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的内容可阅读我之前关于进程的文章。
一开始我以为是redis,各种MQ之类的基于TCP的消息队列。但其实是操作系统内的消息队列,node暂时没有提供相关的上层接口,需要更底层实现,e.g. svmq
更多node相关知识,请访问:nodejs 教程!!
Das obige ist der detaillierte Inhalt vonDetaillierte Erläuterung verschiedener Implementierungsmethoden der Prozesskommunikation im Knoten. Für weitere Informationen folgen Sie bitte anderen verwandten Artikeln auf der PHP chinesischen Website!