2023. 3. 5. 14:48γμΈμ΄/Javascript(Node, TS...)

NodeJS λ°νμμμ μλ‘μ΄ νλ‘μΈμ€λ₯Ό μμ±νκ³ μΆλ€λ©΄
μΌλ°μ μΌλ‘ Child_process ν¨ν€μ§μ λ€μμ λ©μλλ€μ νμ©ν μ μλ€.
- Child_process.fork()
- Child_process.exec()
- Child_process.spawn()
μ¬κΈ°μμλ μ λ©μλλ€μ΄ μλνλ λ°©μμ λλͺ μ μμ€ν μ½λ€κ³Ό μ°κ΄ μ§μ΄ λΉκ΅νκ³ μ νλ€.
λ€μ΄κ°κΈ° μ μ...
μ΄ κΈμ μ΄ν΄νκΈ° μν΄μλ μμ€ν μ½κ³Ό μμ€ν μ½μ μ’ λ₯μΈ fork()μ exec()μ΄ λ¬΄μμΈμ§ μμμΌνλ€.
μ΄λ€μ λν΄ λ¨Όμ κ°λ¨νκ² μκ°νκ³ λμ΄κ°κ² λ€.
μμ€ν μ½
μμ€ν μ½μ΄λ μ μ λͺ¨λμμ μλνλ νλ‘μΈμ€λ€μ΄ μ΄μ체μ μ κΆνμ΄ νμν μμ μ μ΄μ체μ μ μμ²νκΈ° μν΄ νΈμΆλλ μΈν°νμ΄μ€λ₯Ό μλ―Ένλ€.
νμΌ μ μΆλ ₯μ΄λ νλ‘μΈμ€μ μμ± λ° μ€ν λ±μ μμ μ λν κΆνμ΄ νλ‘μΈμ€λ€μκ² μμ κ²½μ°
μ»΄ν¨ν°λ μΈλΆ 곡격μΌλ‘λΆν° λ§€μ° μ·¨μ½ν΄μ§κΈ° λλ¬Έμ,
ν΄λΉ μμ λ€μ λν κΆνμ μ΄μ체μ μκ² μμΌλ©° νλ‘μΈμ€λ€μ μ΄μ체μ μ μ΄λ₯Ό μμ²νλ λ°©μμΌλ‘ μλνλ€.
fork()
fork() λ νλ‘μΈμ€λ₯Ό μμ±νλ μμ€ν μ½λ‘, λΆλͺ¨ νλ‘μΈμ€λ₯Ό 볡μ¬νλ λ°©μμΌλ‘ μλνλ€.
fork() κ° νΈμΆλ μμ μ μ€ν 컨ν μ€νΈλ₯Ό μμ ν 볡μ¬νκΈ° λλ¬Έμ,
μμ νλ‘μΈμ€λ λΆλͺ¨ νλ‘μΈμ€ μ½λμ μμ μ§μ λΆν° μ€νλλ κ²μ΄ μλ fork() νΈμΆ μ΄νμ μ½λ νλ¦μ΄ μ€νλλ€.
fork() μ λ°ν κ°μ λΆλͺ¨μ μμμμ μλ‘ λ€λ₯Έλ°, λΆλͺ¨ νλ‘μΈμ€μμλ μμ νλ‘μΈμ€μ Idκ° λ°νλκ³ μμ νλ‘μΈμ€μμλ 0μ΄ λ°νλλ€.
λ°λΌμ fork() νΈμΆ μ΄ν if λΆκΈ°λ₯Ό ν΅ν΄ λ€λ₯Έ μ½λ νλ¦μ΄ μ€νλλλ‘ μ½λλ₯Ό ꡬμ±ν μ μλ€.
exec()
exec() λ fork()μλ λ¬λ¦¬ μλ‘μ΄ νλ‘μΈμ€λ₯Ό μμ±νλ μμ€ν μ½μ΄ μλλ€.
exec() μ΄ νΈμΆλλ©΄ κΈ°μ‘΄ νλ‘μΈμ€λ₯Ό μλ‘μ΄ νλ‘μΈμ€λ‘ μμ ν λ체νλ€. λ°λΌμ μλ‘μ΄ μ½λ νλ¦μ΄ μλνκΈ°λ νμ§λ§ κΈ°μ‘΄ νλ‘μΈμ€λ μμ ν μ¬λΌμ§κ² λλ€.
리λ μ€μμλ fork()μ exec()μ μ‘°ν©μ ν΅ν΄ μμ ꡬννκ³ μλ€.
Spawn λ©μλ
μ΄μ λ³Έλ‘ μΌλ‘ λμμμ, Child_process ν¨ν€μ§μ νλ‘μΈμ€ μμ± λ©μλλ€μ λ€μ¬λ€λ³΄μ.
NodeJS 곡μ λ¬Έμμ μμ±λ spawn λ©μλμ μ¬μ© μμλ λ€μκ³Ό κ°λ€.
const { spawn } = require('node:child_process');
const ls = spawn('ls', ['-lh', '/usr']);
ls.stdout.on('data', (data) => {
console.log(`stdout: ${data}`);
});
ls.stderr.on('data', (data) => {
console.error(`stderr: ${data}`);
});
ls.on('close', (code) => {
console.log(`child process exited with code ${code}`);
});
spawn λ©μλλ λͺ λ Ήμ΄μ μΈμλ€μ μ λ ₯ λ°κ³ μ΄λ₯Ό μ΄μ©νμ¬ μλ‘μ΄ νλ‘μΈμ€λ₯Ό μμ±νλ€.
ν΄λΉ λ©μλλ ChildProcess κ°μ²΄λ₯Ό λ°ννκ³ , μ΄ν νμ€ μ μΆλ ₯μ ν΅ν΄ λΆλͺ¨μ μμ κ° λ°μ΄ν° μ μ‘(IPC)μ΄ κ°λ₯νλ€.
μ΄ λ λ°μ΄ν°λ Streamμ ννλ₯Ό λκ² λλ€.
spawn λ©μλκ° μ€νλλ©΄ μ°¨λ‘λλ‘ fork(), exec() μμ€ν μ½μ΄ νΈμΆλκ³ , μΆκ°μ μΌλ‘ IPCλ₯Ό μν pipe() λ νΈμΆλλ€.
μ΄ λ execμΌλ‘ λͺ λ Ήμ΄λ₯Ό μ§μ μ€ννκΈ° λλ¬Έμ μμ κ΄μ¬νμ§ μλλ€.
Exec λ©μλ
곡μ λ¬Έμμ exec() λ©μλ μμλ λ€μκ³Ό κ°λ€.
const { exec } = require('node:child_process');
exec('cat *.js missing_file | wc -l', (error, stdout, stderr) => {
if (error) {
console.error(`exec error: ${error}`);
return;
}
console.log(`stdout: ${stdout}`);
console.error(`stderr: ${stderr}`);
});
exec() λ©μλλ exec() μμ€ν μ½κ³Ό λ¬λ¦¬, μλ‘μ΄ νλ‘μΈμ€λ₯Ό μμ±νλ€.
λͺ λ Ήμ΄λ₯Ό νλμ λ¬Έμμ΄μ λͺ¨λ λ΄μ νΈμΆνκ³ , μμκ³Ό λΆλͺ¨ κ°μ ν΅μ μ ν¨κ» μ λ¬λλ μ½λ°± ν¨μλ₯Ό ν΅ν΄ μ΄λ£¨μ΄μ§λ€.
spawn() λ©μλμ κΈ°λ₯ μ μ μ¬ν΄ 보μ΄λ μ΄λ° μ°¨μ΄κ° μ‘΄μ¬νλ μ΄μ κ° λκΉ?
spawn() vs exec()
λ λ©μλμ μ°¨μ΄λ ν¬κ² 2κ°μ§μ΄λ€.
- λͺ λ Ήμ΄ μ λ¬ λ°©μ
- λΆλͺ¨ μμ κ°μ ν΅μ ꡬν λ°©μ
첫λ²μ§Έ μ°¨μ΄μ μ΄μ λ λ°λ‘ μμ μ€ν μ 무μ΄λ€.
spawn()μ μμ μ€νμν€μ§ μμ§λ§ exec()μ μμ μ€νμν¨λ€.
ꡬ체μ μΌλ‘, exec() λ©μλλ λ΄λΆμ μΌλ‘ spawn() λ©μλλ₯Ό μ΄μ©νμ¬ μμ μ€νμν€κ³ ν΄λΉ μμμ λͺ λ Ήμ΄λ₯Ό μ€νμν€λ λ°©μμΌλ‘ μλνλ€.
μ΄λ‘ μΈν΄ exec() λ©μλμμλ μμμ μ 곡νλ κΈ°λ₯μ μ΄μ©μ΄ κ°λ₯νλ€. μμλ‘λ μμ νμ΄ν κΈ°λ₯μ΄ μλ€. (λͺ λ Ήμ΄ μ°κ²° κΈ°λ₯, pipe() μμ€ν μ½κ³Ό μμ ν λ€λ¦)
λ°λΌμ spawn() λ©μλμλ νλμ λͺ λ Ήμ΄λ§ μ λ¬ν μ μμΌλ, exec() λ©μλλ μ¬λ¬ λͺ λ Ήμ΄λ₯Ό μ°κ²°νμ¬ μ λ¬ν μ μλ€.
λλ²μ§Έ μ°¨μ΄μ μ΄μ λ νλ‘μΈμ€ κ° λ°μ΄ν° ν΅μ μ μ΄μ©λλ λ°©μμ μλ€.
spawn() λ©μλλ Streamμ μ΄μ©νλ€. μ΄μ μ€μκ°μΌλ‘ λ°μ΄ν°λ₯Ό μμ ν μ μμ΄μΌνκΈ° λλ¬Έμ μ΄λ²€νΈ λ±λ‘ λ°©μμΌλ‘ λ°μ΄ν°λ₯Ό μ£Όκ³ λ°λλ€.
exec() λ©μλλ Bufferedμ μ΄μ©νλ€. μ¦, μμ νλ‘μΈμ€μ λ°μ΄ν°λ₯Ό 차곑차곑 μμ νλ²μ μ λ¬νκΈ° λλ¬Έμ νλμ μ½λ°±μμ λͺ¨λ μμ μ΄ κ°λ₯νλ€.
μ΄λ¬ν μ°¨μ΄ λλ¬Έμ λκ·λͺ¨ λ°μ΄ν°μ μ‘μμ μ΄ νμν λμλ Streamμ μ΄μ©νλ spawn() λ©μλκ° μ 리νλ€.
exec() λ©μλλ₯Ό νμ©νλ€λ©΄ λ°μ΄ν° μ²λ¦¬λ₯Ό μν μ€λ²ν€λκ° μ»€μ§κ³ , λ°μ΄ν°κ° λ무 컀μ§λ κ²½μ°μλ μμ μλ¬κ° λ°μνλ€.
Fork λ©μλ
곡μλ¬Έμμ fork() λ©μλ μμ λ λ€μκ³Ό κ°λ€.
if (process.argv[2] === 'child') {
setTimeout(() => {
console.log(`Hello from ${process.argv[2]}!`);
}, 1_000);
} else {
const { fork } = require('node:child_process');
const controller = new AbortController();
const { signal } = controller;
const child = fork(__filename, ['child'], { signal });
child.on('error', (err) => {
// This will be called with err being an AbortError if the controller aborts
});
controller.abort(); // Stops the child process
}
μ μμλ μ€μ€λ‘μ 볡μ¬λ³Έμ λ§λλ μμλ‘, μμ€ν μ½μ forkμ μ μ¬νκ² λμνμ§λ§ Child processμ fork() λ©μλλ λ€λ₯Έ js νμΌμ λν΄μλ μλνλ€. μμλ μλμ κ°λ€.
// parent.js
const { fork } = require('child_process');
const path = require('path');
const child = fork(path.join(__dirname, 'child.js'));
child.on('message', (msg) => {
console.log(`Parent process received message: ${msg}`);
});
child.send('Hello from parent process!');
// child.js
process.on('message', (msg) => {
console.log(`Child process received message: ${msg}`);
process.send('Hello from child process!');
});
μ μμλ₯Ό ν΅ν΄ μ μ μλ μ μ μ°μ fork() λ©μλλ μ€μ§ NodeJS (jsνμΌ)μ λν΄μλ§ μλνλ€λ κ²μ΄λ€.
NodeJS 곡μλ¬Έμμμλ fork() λ©μλλ spawn() λ©μλμ μ€νμ μΌμ΄μ€(Node λͺ λ Ήμ΄ μν)λΌκ³ μΈκΈνκ³ μλ€.
The child_process.fork() method is a special case of child_process.spawn() used specifically to spawn new Node.js processes.
λν μμ νλ‘μΈμ€(child.js)μμ νΉλ³ν μ€μ μμ΄ process κ°μ²΄μ μ κ·Όνμ¬ λΆλͺ¨ νλ‘μΈμ€μ ν΅μ μ μννλλ°, μ΄λ fork() λ©μλλ₯Ό ν΅ν΄ μ€νλ νλ‘μΈμ€λ κΈ°λ³Έμ μΌλ‘ λΉνΈμΈ IPC ꡬμ±μ ν¬ν¨νκ³ μκΈ° λλ¬Έμ΄λ€.
λ°λΌμ fork() λ©μλλ₯Ό νμ©νλ©΄ Node νλ‘μΈμ€ κ°μ Stream ν΅μ μ μ½κ² ꡬνν μ μλ€.
μ°Έμ‘°
https://nodejs.org/api/child_process.html#child-process
https://stackoverflow.com/questions/48698234/node-js-spawn-vs-execute
https://stackoverflow.com/questions/17861362/node-js-child-process-difference-between-spawn-fork
Child process | Node.js v19.7.0 Documentation
Child process# Source Code: lib/child_process.js The node:child_process module provides the ability to spawn subprocesses in a manner that is similar, but not identical, to popen(3). This capability is primarily provided by the child_process.spawn() functi
nodejs.org
Node.js Spawn vs. Execute
In an online training video I am watching to learn Node, the narrator says that "spawn is better for longer processes involving large amounts of data, whereas execute is better for short bits of da...
stackoverflow.com
node.js child process - difference between spawn & fork
This might seem like a basic question, but I could not find any documentation : What is the difference between forking & spawning a node.js process? I have read that forking is a special case of
stackoverflow.com
'μΈμ΄ > Javascript(Node, TS...)' μΉ΄ν κ³ λ¦¬μ λ€λ₯Έ κΈ
Interface vs Abstract Class (in Typescript) (0) | 2023.03.19 |
---|---|
Interface in TS (vs Java) (0) | 2023.03.19 |
TypeScript νμ : any, unknown, never (0) | 2023.03.09 |