


Analisis mendalam tentang cara membuat proses anak dalam Node.js
Artikel ini akan membawa anda melalui sub-proses dalam Node.js dan memperkenalkan empat kaedah untuk mencipta sub-proses dalam Node.js saya harap ia akan membantu semua orang.
Seperti yang kita semua tahu, Node.js ialah bahasa pengaturcaraan berbenang tunggal, tak segerak, tidak menyekat, jadi bagaimana untuk menggunakan sepenuhnya kelebihan berbilang teras CPU? Ini memerlukan modul child_process untuk mencipta proses anak Dalam Node.js, terdapat empat cara untuk mencipta proses anak:
-
exec
execFile
spawn
fork
[Pembelajaran yang disyorkan: "tutorial nodejs "]
Empat kaedah di atas akan mengembalikan contoh ChildProcess
(diwarisi daripada EventEmitter
), yang mempunyai tiga aliran stdio Standard :
child.stdin
child.stdout
child.stderr
Peristiwa yang boleh didaftarkan dan dipantau semasa kitaran hayat proses anak ialah:
exit
: dicetuskan apabila proses anak tamat, dan parameternya ialah kod ralat kod dan isyarat gangguan isyarat.
close
: Dicetuskan apabila proses anak tamat dan strim stdio ditutup Parameternya adalah sama dengan acara exit
.
disconnect
: Dicetuskan apabila proses induk memanggil child.disconnect()
atau proses anak memanggil process.disconnect()
.
error
: Dicetuskan apabila proses anak tidak boleh dibuat, tidak boleh dibunuh atau gagal menghantar mesej kepada proses anak.
message
: Dicetuskan apabila proses anak menghantar mesej melalui process.send()
.
spawn
: Dicetuskan apabila proses anak berjaya dibuat (acara ini hanya ditambahkan dalam Node.js v15.1).
Kaedah exec
dan execFile
juga menyediakan fungsi panggil balik tambahan, yang akan dicetuskan apabila proses anak ditamatkan. Seterusnya, analisis terperinci:
exec
kaedah exec digunakan untuk melaksanakan perintah bash dan parameternya ialah rentetan arahan. Sebagai contoh, untuk mengira bilangan fail dalam direktori semasa, fungsi exec ditulis sebagai:
const { exec } = require("child_process") exec("find . -type f | wc -l", (err, stdout, stderr) => { if (err) return console.error(`exec error: ${err}`) console.log(`Number of files ${stdout}`) })
exec akan mencipta sub-proses baharu, kemudian cache hasil berjalannya dan panggil fungsi panggil balik selepas operasi selesai.
Anda mungkin terfikir bahawa arahan exec berbahaya Jika anda menggunakan rentetan yang disediakan oleh pengguna sebagai parameter fungsi exec, anda akan menghadapi risiko suntikan baris arahan, contohnya:
.find . -type f | wc -l; rm -rf /;
Selain itu, memandangkan exec akan cache semua hasil output dalam ingatan, apabila data agak besar, spawn akan menjadi pilihan yang lebih baik.
execFile
Perbezaan antara execFile dan exec ialah ia tidak mencipta shell, tetapi secara langsung melaksanakan arahan, jadi ia lebih cekap, contohnya:
const { execFile } = require("child_process") const child = execFile("node", ["--version"], (error, stdout, stderr) => { if (error) throw error console.log(stdout) })
Oleh kerana Tiada cangkerang dicipta, dan parameter program dihantar sebagai tatasusunan, jadi ia mempunyai keselamatan yang tinggi.
spawn
Fungsi spawn adalah serupa dengan execFile Cangkang tidak didayakan secara lalai, tetapi perbezaannya ialah execFile mencache keluaran baris arahan dan kemudian menghantar hasilnya ke dalam panggilan balik. fungsi, manakala spawn menggunakan output aliran, dengan aliran, ia adalah sangat mudah untuk menyambung input dan output Contohnya, perintah wc
biasa:
const child = spawn("wc") process.stdin.pipe(child.stdin) child.stdout.on("data", data => { console.log(`child stdout:\n${data}`) })
Pada masa ini, input akan diperolehi. daripada stdin baris arahan Apabila pengguna mencetuskan Apabila anda menekan Enter ctrl D
, anda mula melaksanakan arahan dan mengeluarkan hasil daripada stdout.
wc ialah singkatan Word Count, yang digunakan untuk mengira bilangan perkataan Sintaksnya ialah:
wc [OPTION]... [FILE]...Salin selepas log masukJika anda memasukkan arahan wc pada terminal dan. tekan Enter, statistik pada masa ini ialah Masukkan aksara dalam terminal daripada papan kekunci, tekan kekunci Enter sekali lagi, dan kemudian tekan
Ctrl D
untuk mengeluarkan keputusan statistik.
Anda juga boleh menggabungkan perintah kompleks melalui paip, seperti mengira bilangan fail dalam direktori semasa Dalam baris arahan Linux, ia akan ditulis seperti ini:
find . -type f | wc -l
Dalam Node.js Kaedah penulisan adalah sama seperti baris arahan:
const find = spawn("find", [".", "-type", "f"]) const wc = spawn("wc", ["-l"]) find.stdout.pipe(wc.stdin) wc.stdout.on("data", (data) => { console.log(`Number of files ${data}`) })
spawn mempunyai konfigurasi tersuai yang kaya, contohnya:
const child = spawn("find . -type f | wc -l", { stdio: "inherit", // 继承父进程的输入输出流 shell: true, // 开启命令行模式 cwd: "/Users/keliq/code", // 指定执行目录 env: { ANSWER: 42 }, // 指定环境变量(默认是 process.env) detached: true, // 作为独立进程存在 })
garpu
Fungsi garpu ialah varian fungsi spawn, saluran komunikasi akan dibuat secara automatik antara proses anak yang dibuat menggunakan garpu dan proses induk, dan kaedah hantar akan dipasang pada proses objek global proses anak. Contohnya, kod parent.js proses induk:
const { fork } = require("child_process") const forked = fork("./child.js") forked.on("message", msg => { console.log("Message from child", msg); }) forked.send({ hello: "world" })
Kod child.js proses anak:
process.on("message", msg => { console.log("Message from parent:", msg) }) let counter = 0 setInterval(() => { process.send({ counter: counter++ }) }, 1000)
Apabila memanggil fork("child.js")
, nod sebenarnya digunakan untuk melaksanakan fail Kod dalam adalah bersamaan dengan spawn('node', ['./child.js'])
. Senario aplikasi biasa
fork adalah seperti berikut: Jika anda menggunakan Node.js untuk mencipta perkhidmatan http, apabila laluannya compute
, operasi yang memakan masa dilakukan.
const http = require("http") const server = http.createServer() server.on("request", (req, res) => { if (req.url === "/compute") { const sum = longComputation() return res.end(Sum is ${sum}) } else { res.end("OK") } }) server.listen(3000);
Anda boleh menggunakan kod berikut untuk mensimulasikan operasi yang memakan masa ini:
const longComputation = () => { let sum = 0; for (let i = 0; i < 1e9; i++) { sum += i } return sum }
那么在上线后,只要服务端收到了 compute
请求,由于 Node.js 是单线程的,耗时运算占用了 CPU,用户的其他请求都会阻塞在这里,表现出来的现象就是服务器无响应。
解决这个问题最简单的方法就是把耗时运算放到子进程中去处理,例如创建一个 compute.js
的文件,代码如下:
const longComputation = () => { let sum = 0; for (let i = 0; i < 1e9; i++) { sum += i; } return sum } process.on("message", msg => { const sum = longComputation() process.send(sum) })
再把服务端的代码稍作改造:
const http = require("http") const { fork } = require("child_process") const server = http.createServer() server.on("request", (req, res) => { if (req.url === "/compute") { const compute = fork("compute.js") compute.send("start") compute.on("message", sum => { res.end(Sum is ${sum}) }) } else { res.end("OK") } }) server.listen(3000)
这样的话,主线程就不会阻塞,而是继续处理其他的请求,当耗时运算的结果返回后,再做出响应。其实更简单的处理方式是利用 cluster 模块,限于篇幅原因,后面再展开讲。
总结
掌握了上面四种创建子进程的方法之后,总结了以下三条规律:
- 创建 node 子进程用 fork,因为自带通道方便通信。
- 创建非 node 子进程用 execFile 或 spawn。如果输出内容较少用 execFile,会缓存结果并传给回调方便处理;如果输出内容多用 spawn,使用流的方式不会占用大量内存。
- 执行复杂的、固定的终端命令用 exec,写起来更方便。但一定要记住 exec 会创建 shell,效率不如 execFile 和 spawn,且存在命令行注入的风险。
更多编程相关知识,请访问:编程视频!!
Atas ialah kandungan terperinci Analisis mendalam tentang cara membuat proses anak dalam Node.js. Untuk maklumat lanjut, sila ikut artikel berkaitan lain di laman web China PHP!

Alat AI Hot

Undresser.AI Undress
Apl berkuasa AI untuk mencipta foto bogel yang realistik

AI Clothes Remover
Alat AI dalam talian untuk mengeluarkan pakaian daripada foto.

Undress AI Tool
Gambar buka pakaian secara percuma

Clothoff.io
Penyingkiran pakaian AI

AI Hentai Generator
Menjana ai hentai secara percuma.

Artikel Panas

Alat panas

Notepad++7.3.1
Editor kod yang mudah digunakan dan percuma

SublimeText3 versi Cina
Versi Cina, sangat mudah digunakan

Hantar Studio 13.0.1
Persekitaran pembangunan bersepadu PHP yang berkuasa

Dreamweaver CS6
Alat pembangunan web visual

SublimeText3 versi Mac
Perisian penyuntingan kod peringkat Tuhan (SublimeText3)

Topik panas



Perkhidmatan Node yang dibina berdasarkan bukan sekatan dan dipacu peristiwa mempunyai kelebihan penggunaan memori yang rendah dan sangat sesuai untuk mengendalikan permintaan rangkaian besar-besaran. Di bawah premis permintaan besar-besaran, isu yang berkaitan dengan "kawalan memori" perlu dipertimbangkan. 1. Mekanisme kutipan sampah V8 dan had ingatan Js dikawal oleh mesin kutipan sampah

Artikel ini akan memberi anda pemahaman yang mendalam tentang memori dan pengumpul sampah (GC) enjin NodeJS V8 saya harap ia akan membantu anda!

Modul fail ialah enkapsulasi operasi fail asas, seperti membaca/menulis/membuka/menutup/memadam fail, dsb. Ciri terbesar modul fail ialah semua kaedah menyediakan dua versi **segerak** dan ** asynchronous**, dengan Kaedah dengan akhiran penyegerakan adalah semua kaedah penyegerakan, dan kaedah yang tidak semuanya adalah kaedah heterogen.

Memilih imej Docker untuk Node mungkin kelihatan seperti perkara remeh, tetapi saiz dan potensi kelemahan imej itu boleh memberi kesan yang ketara pada proses dan keselamatan CI/CD anda. Jadi bagaimana kita memilih imej Node.js Docker yang terbaik?

Node 19 telah dikeluarkan secara rasmi Artikel ini akan memberi anda penjelasan terperinci tentang 6 ciri utama Node.js 19. Saya harap ia akan membantu anda!

Bagaimanakah Node.js melakukan GC (pengumpulan sampah)? Artikel berikut akan membawa anda melaluinya.

Gelung peristiwa ialah bahagian asas Node.js dan mendayakan pengaturcaraan tak segerak dengan memastikan bahawa utas utama tidak disekat Memahami gelung peristiwa adalah penting untuk membina aplikasi yang cekap. Artikel berikut akan memberi anda pemahaman yang mendalam tentang gelung acara dalam Node.

Sebab mengapa nod tidak boleh menggunakan arahan npm adalah kerana pembolehubah persekitaran tidak dikonfigurasikan dengan betul Penyelesaiannya ialah: 1. Buka "Sistem Sifat"; 2. Cari "Pembolehubah Persekitaran" -> "Pembolehubah Sistem", dan kemudian edit persekitaran. pembolehubah; 3. Cari lokasi folder nodejs;
