찾다
웹 프론트엔드JS 튜토리얼Node.js의 child_process 모듈에서 상위 프로세스와 하위 프로세스 간의 통신을 학습하기 위한 샘플 코드에 대한 자세한 설명

이 글은 주로 Node.js의 기본 사항을 소개합니다. child_process 모듈에는 부모 프로세스와 자식 프로세스 간의 통신을 학습하는 특정 참조 값이 있습니다. 관심 있는 친구들은 이를 참조할 수 있습니다.

child_process 모듈은 자체 프로세스를 생성하기 위해 popen(3)과 동일한 방법을 제공합니다. 함수는 주로 child_process.spawnfunction:

const spawn = require('child_process').spawn; 
const ls = spawn('ls', ['-lh', '/usr']); 
ls.stdout.on('data', (data) => { 
 console.log(`stdout: ${data}`); 
}); 
ls.stderr.on('data', (data) => { 
 console.log(`stderr: ${data}`); 
}); 
ls.on('close', (code) => { 
 console.log(`child process exited with code $[code]`); 
});

을 통해 제공됩니다. 기본적으로 Node.js 프로세스와 자식 프로세스 사이에 stdin, stdout, stderr 파이프가 이미 존재합니다. 메서드는 비차단 방식으로 데이터를 전달할 수 있습니다. (일부 프로그램은 내부적으로 라인 버퍼링된 I/O를 사용한다는 점에 유의하세요. 이는 Node.js에 영향을 미치지 않으므로 자식에게 전달한다는 의미입니다. 프로세스의 데이터가 즉시 소비되지 않을 수 있습니다.) )

chid-process의 생성 메소드는 프로세스에서 비동기 방식으로 생성되므로 Node.js의 루프를 차단하지 않습니다. , 그러나 child-process.spawnSync 메소드는 생성된 프로세스가 종료되거나 종료될 때까지 이벤트 루프를 차단합니다.
child_process.exec: 셸 클라이언트가 생성됩니다. 셸을 사용하여 프로그램을 실행합니다. 완료되면

콜백 함수

stdout 및 stderr
child_process.execFile에 전달됩니다. exec와 유사하지만 A는 아닙니다. 쉘이 즉시 생성됩니다


child_process.fork: 새로운 Node.js 프로세스를 생성하고 특정 모듈을 실행하여 IPC 채널을 생성한 다음 상위 프로세스와 하위 프로세스 간에 데이터를 전송합니다


child_process.execSync: exec와 차이점은 Node.js의 이벤트 루프를 차단한다는 점입니다. 그러나 child-process


child_process.execFileSync: 차이점은 다음과 같습니다. execFile은 Node.js 이벤트 루프를 차단한다는 점입니다. 그러나 자동화된 쉘 스크립트와 같은 일부 특수한 경우에는 동기식 방법이 더 유용할 수 있습니다. 루프


child_process.spawn(), child_process.fork(), child_process.exec() 및 child_process.execFile()은 모두 비동기

API

입니다. 각 메소드는 ChildProcess 인스턴스를 생성하며 이 객체 는 Node.js의 EventEmitter API를 구현하므로 상위 프로세스는 수신 함수를 등록하고 하위 프로세스의 특정 이벤트가 트리거될 때 호출될 수 있습니다. child_process.exec() 및 child_process.execFile()은 하위 프로세스가 종료될 때 호출되는 선택적 콜백 함수를 지정할 수 있습니다.

Windows 플랫폼에서 .bat 및 .cmd 실행:


child_process.exec와 child_process.execFile의 차이점은 플랫폼에 따라 다를 수 있습니다. 그리고 다르다. Unit/

Linux

/OSX 플랫폼에서는 execFile이 셸을 생성하지 않기 때문에 더 효율적입니다. Windows에서는 터미널 없이는 .bat/.cmd를 실행할 수 없으므로 execFile을 사용할 수 없습니다(child_process.spawn도 사용할 수 없음). Windows에서 .bat/.cmd는 generate 메서드를 사용하고 셸 옵션을 지정하거나 child_process.exec를 사용하거나 cmd.exe를 생성하고 .bat/.cmd 파일을 매개변수로 전달할 수 있습니다(child_process.exec는 이렇게 하세요).

const spawn = require('child_process').spawn; 
const bat = spawn('cmd.exe', ['/c', 'my.bat']);//使用shell方法指定一个shell选项 
bat.stdout.on('data', (data) => { 
 console.log(data); 
}); 
bat.stderr.on('data', (data) => { 
 console.log(data); 
}); 
 
bat.on('exit', (code) => { 
 console.log(`Child exited with code $[code]`); 
});
또는 다음 방법을 사용할 수도 있습니다:

const exec = require('child_process').exec;//产生exec,同时传入.bat文件 
exec('my.bat', (err, stdout, stderr) => { 
 if (err) { 
  console.error(err); 
  return; 
 } 
 console.log(stdout); 
});

child_process.exec(command[, options][, callback])

const exec = require('child_process').exec; 
const child = exec('cat *.js bad_file | wc -l', 
 (error, stdout, stderr) => { 
  console.log(`stdout: ${stdout}`); 
  console.log(`stderr: ${stderr}`); 
  if (error !== null) { 
   console.log(`exec error: ${error}`); 
  } 
});

위 코드는 셸을 생성한 다음 이 셸을 사용하여 명령을 실행하고 결과를 캐시합니다. 콜백 함수의 error.code 속성은 하위 프로세스의 종료 코드를 나타내고, error.signal은 프로세스 종료 신호를 나타내며, 0이 아닌 코드는 오류를 나타냅니다. 기본 옵션 매개변수 값은 다음과 같습니다.

{ 
 encoding: 'utf8', 
 timeout: 0, 
 maxBuffer: 200*1024,//stdout和stderr允许的最大的比特数据,超过她子进程就会被杀死 
 killSignal: 'SIGTERM', 
 cwd: null, 
 env: null 
}

시간 초과가 0이 아니면 상위 프로세스는 신호를 보냅니다. 이 신호는 killSignal에 의해 지정되며 하위 프로세스를 종료합니다. 하위 프로세스가 지정된 시간 초과를 초과하는 경우. 참고: POSIX 시스템에서 exec 메소드를 호출하는 것과 달리 child_process.exec는 현재 스레드를 대체하지 않지만 셸을 사용하여

child_process.execFile(file[, args][ , options 명령을 실행합니다. ][, 콜백])

여기서 file은 실행해야 하는 파일을 나타냅니다. child_process.execFile()은 exec와 매우 유사하지만 이 메서드는 쉘을 생성하지 않습니다. 지정된 실행 파일은 즉시 새 스레드를 생성하므로 효율이 child_process.exec보다 높습니다.

const execFile = require('child_process').execFile; 
const child = execFile('node', ['--version'], (error, stdout, stderr) => { 
 if (error) { 
  throw error; 
 } 
 console.log(stdout); 
});

因为不会产生shell,一些I/O redirection和file globbing这些行为不支持

child_process.fork(modulePath[, args][, options])

其中modulePath表示要在子线程中执行的模块。其中options中的参数silent如果设置为true,那么子进程的stdin, stdout, stderr将会被传递给父进程,如果设置为false那么就会从父进程继承。execArgv默认的值为process.execArgv,execPath表示用于创建子进程的可执行文件。这个fork方法是child_process.spawn的一种特殊用法,用于产生一个Node.js的子进程,和spawn一样返回一个ChildProcess对象。返回的ChildProcess会有一个内置的传输通道用于在子进程和父进程之间传输数据(用ChildProcess的send方法完成)。我们必须注意,产生的Node.js进程和父进程之间是独立的,除了他们之间的IPC传输通道以外。每一个进程有独立的内存,有自己独立的V8引擎。由于产生一个子进程需要其他额外的资源分配,因此产生大量的子进程不被提倡。默认情况下,child_process.fork会使用父进程的process.execPath来产生一个Node.js实例,options中的execPath允许指定一个新的路径。通过指定execPath产生的新的进程和父进程之间通过文件描述符(子进程的环境变量NODE_CHANNEL_FD)来通信。这个文件描述符上的input/output应该是一个JSON对象。和POSIX系统调用fork不一样的是,child_process.fork不会克隆当前的进程

最后,我们来看看子进程和父进程之间是如何通信的:

服务器端的代码:

var http = require('http'); 
var cp = require('child_process'); 
var server = http.createServer(function(req, res) { 
  var child = cp.fork(dirname + '/cal.js'); 
  //每个请求都单独生成一个新的子进程 
  child.on('message', function(m) { 
    res.end(m.result + '\n'); 
  }); 
  //为其指定message事件 
  var input = parseInt(req.url.substring(1)); 
  //和postMessage很类似,不过这里是通过send方法而不是postMessage方法来完成的 
  child.send({input : input}); 
}); 
server.listen(8000);

子进程的代码:

function fib(n) { 
  if (n < 2) { 
    return 1; 
  } else { 
    return fib(n - 2) + fib(n - 1); 
  } 
} 
//接受到send传递过来的参数 
process.on(&#39;message&#39;, function(m) { 
  //console.log(m); 
  //打印{ input: 9 } 
  process.send({result: fib(m.input)}); 
});

child_process.spawn(command[, args][, options])

其中options对象的stdio参数表示子进程的stdio配置;detached表示让子进程在父进程下独立运行,这个行为与平台有关;shell如果设置为true那么就会在shell中执行命令。这个方法通过指定的command来产生一个新的进程,如果第二个参数没有指定args那么默认就是一个空的数组,第三个参数默认是如下对象,这个参数也可以用于指定额外的参数:

{
 cwd: undefined, //产生这个进程的工作目录,默认继承当前的工作目录
 env: process.env//这个参数用于指定对于新的进程可见的环境变量,默认是process.env
}

其中cwd用于指定子进程产生的工作目录,如果没有指定表示的就是当前工作目录。env用于指定新进程的环境变量,默认为process.env。下面的例子展示了使用ls -lh/usr来获取stdout,stderr以及exit code:

const spawn = require(&#39;child_process&#39;).spawn; 
const ls = spawn(&#39;ls&#39;, [&#39;-lh&#39;, &#39;/usr&#39;]); 
ls.stdout.on(&#39;data&#39;, (data) => { 
 console.log(`stdout: ${data}`); 
}); 
ls.stderr.on(&#39;data&#39;, (data) => { 
 console.log(`stderr: ${data}`); 
}); 
ls.on(&#39;close&#39;, (code) => { 
 console.log(`child process exited with code $[code]`); 
});

下面是一个很详细的运行"ps ax|grep ssh"的例子:

const spawn = require(&#39;child_process&#39;).spawn; 
const ps = spawn(&#39;ps&#39;, [&#39;ax&#39;]); 
const grep = spawn(&#39;grep&#39;, [&#39;ssh&#39;]); 
ps.stdout.on(&#39;data&#39;, (data) => { 
 grep.stdin.write(data); 
}); 
ps.stderr.on(&#39;data&#39;, (data) => { 
 console.log(`ps stderr: ${data}`); 
}); 
ps.on(&#39;close&#39;, (code) => { 
 if (code !== 0) { 
  console.log(`ps process exited with code $[code]`); 
 } 
 grep.stdin.end(); 
}); 
grep.stdout.on(&#39;data&#39;, (data) => { 
 console.log(`${data}`); 
}); 
grep.stderr.on(&#39;data&#39;, (data) => { 
 console.log(`grep stderr: ${data}`); 
}); 
grep.on(&#39;close&#39;, (code) => { 
 if (code !== 0) { 
  console.log(`grep process exited with code $[code]`); 
 } 
});

用下面的例子来检查错误的执行程序:

const spawn = require(&#39;child_process&#39;).spawn; 
const child = spawn(&#39;bad_command&#39;); 
child.on(&#39;error&#39;, (err) => { 
 console.log(&#39;Failed to start child process.&#39;); 
});

options.detached:

在windows上,把这个参数设置为true的话,这时候如果父进程退出了那么子进程还会继续运行,而且子进程有自己的console window。如果把子进程设置了这个为true,那么就不能设置为false了。在非window平台上,如果把这个设置为true,子进程就会成为进程组合和session的leader,这时候子进程在父进程退出以后会继续执行,不管子进程是否detached。可以参见setsid(2)。

默认情况下,父进程会等待detached子进程,然后退出。要阻止父进程等待一个指定的子进程可以使用child.unref方法,这个方法会让父进程的事件循环不包括子进程,这时候允许父进程独立退出,除非在父进程和子进程之间有一个IPC通道。下面是一个detach长期运行的进程然后把它的输出导向到一个文件:

const fs = require(&#39;fs&#39;); 
const spawn = require(&#39;child_process&#39;).spawn; 
const out = fs.openSync(&#39;./out.log&#39;, &#39;a&#39;); 
const err = fs.openSync(&#39;./out.log&#39;, &#39;a&#39;); 
const child = spawn(&#39;prg&#39;, [], { 
 detached: true,//依赖于父进程 
 stdio: [ &#39;ignore&#39;, out, err ] 
}); 
child.unref();//允许父进程单独退出,不用等待子进程

当使用了detached选项去产生一个长期执行的进程,这时候如果父进程退出了那么子进程就不会继续执行了,除非指定了一个stdio配置(不和父进程之间有联系)。如果父进程的stdio是继承的,那么子进程依然会和控制终端之间保持关系。

options.stdio

这个选项用于配置父进程和子进程之间的管道。默认情况下,子进程的stdin,stdout,stderr导向了ChildProcess这个对象的child.stdin,child.stdout,child.stderr流,这和设置stdio为['pipe','pipe','pipe']是一样的。stdio可以是下面的任何一个字符串

'pipe':相当于['pipe','pipe','pipe'],为默认选项

'ignore':相当于['ignore','ignore','ignore']

'inherit':相当于[process.stdin,process.stdout,process.stderr]或者[0,1,2]

一般情况下,stdio是一个数组,每一个选项对应于子进程的fd。其中0,1,2分别对应于stdin,stdout,stderr。如果还设置了多于的fds那么就会用于创建父进程和子进程之间的额外的管道,可以是下面的任何一个值:

'pipe':为子进程和父进程之间创建一个管道。父进程管道的末端会作为child_process对象的ChildProcess.stdio[fd]而存在。fds0-2创建的管道在ChildProcess.stdin,ChildProcess.stdout,ChildProcess.stderr也是存在的

'ipc':用于创建IPC通道用于在父进程和子进程之间传输消息或者文件描述符。ChildProcess对象最多有一个IPC stdio文件描述符,使用这个配置可以启用ChildProcess的send方法,如果父进程在文件描述符里面写入了JSON对象,那么ChildProcess.on("message")事件就会在父进程上触发。如果子进程是Node.js进程,那么ipc配置就会启用子进程的process.send(), process.disconnect(), process.on('disconnect'), and process.on('message')方法。

'ignore':让Node.js子进程忽视文件描述符。因为Node.js总是会为子进程开启fds0-2,设置为ignore就会导致Node.js去开启/dev/null,同时把这个值设置到子进程的fd上面。

'strem':和子进程之间共享一个可读或者可写流,比如file,socket,pipe。这个stream的文件描述符和子进程的文件描述符fd是重复的。注意:流必须有自己的文件描述符

正整数:表示父进程的打开的文件描述符。和stream对象可以共享一样,这个文件描述符在父子进程之间也是共享的
null/undefined:使用默认值。stdio的fds0,1,2管道被创建(stdin,stdout,stderr)。对于fd3或者fdn,默认为'ignore'

const spawn = require(&#39;child_process&#39;).spawn; 
// Child will use parent&#39;s stdios 
//使用父进程的stdios 
spawn(&#39;prg&#39;, [], { stdio: &#39;inherit&#39; }); 
//产生一个共享process.stderr的子进程 
// Spawn child sharing only stderr 
spawn(&#39;prg&#39;, [], { stdio: [&#39;pipe&#39;, &#39;pipe&#39;, process.stderr] }); 
// Open an extra fd=4, to interact with programs presenting a 
// startd-style interface. 
spawn(&#39;prg&#39;, [], { stdio: [&#39;pipe&#39;, null, null, null, &#39;pipe&#39;] });

注意:当子进程和父进程之间建立了IPC通道,同时子进程为Node.js进程,这时候开启的具有IPC通道的子进程(使用unref)直到子进程注册了一个disconnect的事件处理句柄process.on('disconnect'),这样就会允许子进程正常退出而不会由于IPC通道的打开而持续运行。

Class: ChildProcess

这个类的实例是一个EventEmitters,用于代表产生的子进程。这个类的实例不能直接创建,必须使用 child_process.spawn(), child_process.exec(), child_process.execFile(), or child_process.fork()来完成

'close'事件:

其中code表示子进程退出的时候的退出码;signal表示终止子进程发出的信号;这个事件当子进程的stdio stream被关闭的时候触发,和exit事件的区别是多个进程可能共享同一个stdio streams!(所以一个进程退出了也就是exit被触发了,这时候close可能不会触发)

'exit'事件:

其中code表示子进程退出的时候的退出码;signal表示终止子进程发出的信号。这个事件当子进程结束的时候触发,如果进程退出了那么code表示进程退出的exit code,否则没有退出就是null。如果进程是由于收到一个信号而终止的,那么signal就是这个信号,是一个string,默认为null。

注意:如果exit事件被触发了,子进程的stdio stream可能还是打开的;Node.js为SUGUBT,SIGTERM创建信号处理器,而且Node.js进程在收到信号的时候不会马上停止。Node.js会进行一系列的清理工作,然后才re-raise handled signal。见waitpid(2)

'disconnect'事件:

在子进程或者父进程中调用ChildProcess.disconnect()方法的时候会触发。这时候就不能再发送和接受信息了,这是ChildProcess.connected就是false了

'error'事件:

当进程无法产生的时候,进程无法杀死的时候,为子进程发送消息失败的时候就会触发。注意:当产生错误的时候exit事件可能会也可能不会触发。如果你同时监听了exit和error事件,那么就要注意是否会无意中多次调用事件处理函数

'message'事件:

message参数表示一个解析后的JSON对象或者初始值;sendHandle可以是一个net.Socket或者net.Server对象或者undefined。当子进程调用process.send时候触发

child.connected:

调用了disconnect方法后就会是false。表示是否可以在父进程和子进程之间发送和接受数据,当值为false就不能发送数据了
 child.disconnect()

关闭子进程和父进程之间的IPC通道,这时候子进程可以正常退出如果没有其他的连接使得他保持活动。这时候父进程的child.connected和子进程的process.connected就会设置为false,这时候不能传输数据了。disconnect事件当进程没有消息接收到的时候被触发,当调用child.disconnect时候会立即触发。注意:当子进程为Node.js实例的时候如child_process.fork,这时候process.disconnect方法就会在子进程中调用然后关闭IPC通道。

child.kill([signal])

为子进程传入消息,如果没有指定参数那么就会发送SIGTERM信号,可以参见signal(7)来查看一系列信号

const spawn = require(&#39;child_process&#39;).spawn; 
const grep = spawn(&#39;grep&#39;, [&#39;ssh&#39;]); 
grep.on(&#39;close&#39;, (code, signal) => { 
 console.log( 
  `child process terminated due to receipt of signal ${signal}`); 
}); 
// Send SIGHUP to process 
grep.kill(&#39;SIGHUP&#39;);

ChildProcess对象在无法传输信号的时候会触发error事件。为一个已经退出的子进程发送信号虽然无法报错但是可能导致无法预料的结果。特别的,如果这个PID已经被分配给另外一个进程那么这时候也会导致无法预料的结果。

child.pid:

返回进程的PID值

const spawn = require(&#39;child_process&#39;).spawn; 
const grep = spawn(&#39;grep&#39;, [&#39;ssh&#39;]); 
console.log(`Spawned child pid: ${grep.pid}`); 
grep.stdin.end();//通过grep.stdin.end结束

child.send(message[, sendHandle][, callback])

当父子进程之间有了IPC通道,child.send就会为子进程发送消息,当子进程为Node.js实例,那么可以用process.on('message')事件接收

父进程为:

const cp = require(&#39;child_process&#39;); 
const n = cp.fork(`${dirname}/sub.js`); 
n.on(&#39;message&#39;, (m) => { 
 console.log(&#39;PARENT got message:&#39;, m); 
}); 
n.send({ hello: &#39;world&#39; });

子进程为:

process.on(&#39;message&#39;, (m) => { 
 console.log(&#39;CHILD got message:&#39;, m); 
}); 
process.send({ foo: &#39;bar&#39; });

子进程使用process.send方法为父进程发送消息。有一个特例,发送{cmd: 'NODE_foo'}。当一个消息在他的cmd属性中包含一个NODE_前缀会被看做使用Node.js核心(被Node.js保留)。这时候不会触发子进程的process.on('message')。而是使用process.on('internalMessage')事件,同时会被Node.js内部消费,一般不要使用这个方法。sendHandle这个用于给子进程传入一个TCP Server或者一个socket,为process.on('message')回调的第二个参数接受。callback当消息已经发送,但是子进程还没有接收到的时候触发,这个函数只有一个参数成功为null否则为Error对象。如果没有指定callback同时消息也不能发送ChildProcess就会触发error事件。当子进程已经退出就会出现这个情况。child.send返回false如果父子进程通道已经关闭,或者积压的没有传输的数据超过一定的限度,否则这个方法返回true。这个callback方法可以用于实现流控制:

下面是发送一个Server的例子:

const child = require(&#39;child_process&#39;).fork(&#39;child.js&#39;); 
// Open up the server object and send the handle. 
const server = require(&#39;net&#39;).createServer(); 
server.on(&#39;connection&#39;, (socket) => { 
 socket.end(&#39;handled by parent&#39;); 
}); 
server.listen(1337, () => { 
 child.send(&#39;server&#39;, server); 
});

子进程接受这个消息:

process.on(&#39;message&#39;, (m, server) => { 
 if (m === &#39;server&#39;) { 
  server.on(&#39;connection&#39;, (socket) => { 
   socket.end(&#39;handled by child&#39;); 
  }); 
 } 
});

这时候server就被子进程和父进程共享了,一些连接可以被父进程处理,一些被子进程处理。上面的例子如果使用dgram那么就应该监听message事件而不是connection,使用server.bind而不是server.listen,但是当前只在UNIX平台上可行。
下面的例子展示发送一个socket对象(产生两个子进程,处理normal和special优先级):

父进程为:

const normal = require(&#39;child_process&#39;).fork(&#39;child.js&#39;, [&#39;normal&#39;]); 
const special = require(&#39;child_process&#39;).fork(&#39;child.js&#39;, [&#39;special&#39;]); 
// Open up the server and send sockets to child 
const server = require(&#39;net&#39;).createServer(); 
server.on(&#39;connection&#39;, (socket) => { 
 // If this is special priority 
 if (socket.remoteAddress === &#39;74.125.127.100&#39;) { 
  special.send(&#39;socket&#39;, socket); 
  return; 
 } 
 // This is normal priority 
 normal.send(&#39;socket&#39;, socket); 
}); 
server.listen(1337);

子进程为:

process.on(&#39;message&#39;, (m, socket) => { 
 if (m === &#39;socket&#39;) { 
  socket.end(`Request handled with ${process.argv[2]} priority`); 
 } 
});

当socket被发送到子进程的时候那么父进程已经无法追踪这个socket什么时候被销毁的。这时候.connections属性就会成为null,因此我们建议不要使用.maxConnections。注意:这个方法在内部JSON.stringify去序列化消息

child.stderr:

一个流对象,是一个可读流表示子进程的stderr。他是child.stdio[2]的别名,两者表示同样的值。如果子进程是通过stdio[2]产生的,设置的不是pipe那么值就是undefined。

child.stdin:

一个可写的流对象。注意:如果子进程等待读取输入,那么子进程会一直等到流调用了end方法来关闭的时候才会继续读取。如果子进程通过stdio[0]产生,同时不是设置的pipe那么值就是undefined。child.stdin是child.stdio[0]的别名,表示同样的值。

const spawn = require(&#39;child_process&#39;).spawn;  
const grep = spawn(&#39;grep&#39;, [&#39;ssh&#39;]);  
console.log(`Spawned child pid: ${grep.pid}`);  
grep.stdin.end();//通过grep.stdin.end结束

child.stdio:

一个子进程管道的稀疏数组,是 child_process.spawn()函数的stdio选项,同时这个值被设置为pipe。child.stdio[0], child.stdio[1], 和 child.stdio[2]也可以通过child.stdin, child.stdout, 和 child.stderr访问。下面的例子中只有子进程的fd1(也就是stdout)被设置为管道,因此只有父进程的child.stdio[1]是一个流,其他的数组中对象都是null:

const assert = require(&#39;assert&#39;); 
const fs = require(&#39;fs&#39;); 
const child_process = require(&#39;child_process&#39;); 
const child = child_process.spawn(&#39;ls&#39;, { 
  stdio: [ 
   0, // Use parents stdin for child 
   &#39;pipe&#39;, // Pipe child&#39;s stdout to parent 
   fs.openSync(&#39;err.out&#39;, &#39;w&#39;) // Direct child&#39;s stderr to a file 
  ] 
}); 
assert.equal(child.stdio[0], null); 
assert.equal(child.stdio[0], child.stdin); 
assert(child.stdout); 
assert.equal(child.stdio[1], child.stdout); 
assert.equal(child.stdio[2], null); 
assert.equal(child.stdio[2], child.stderr);

child.stdout:

一个可读流,代表子进程的stdout。如果子进程产生的时候吧stdio[1]设置为除了pipe以外的任何数,那么值就是undefined。其值和child.stdio[1]一样

위 내용은 Node.js의 child_process 모듈에서 상위 프로세스와 하위 프로세스 간의 통신을 학습하기 위한 샘플 코드에 대한 자세한 설명의 상세 내용입니다. 자세한 내용은 PHP 중국어 웹사이트의 기타 관련 기사를 참조하세요!

성명
본 글의 내용은 네티즌들의 자발적인 기여로 작성되었으며, 저작권은 원저작자에게 있습니다. 본 사이트는 이에 상응하는 법적 책임을 지지 않습니다. 표절이나 침해가 의심되는 콘텐츠를 발견한 경우 admin@php.cn으로 문의하세요.
Python vs. JavaScript : 개발 환경 및 도구Python vs. JavaScript : 개발 환경 및 도구Apr 26, 2025 am 12:09 AM

개발 환경에서 Python과 JavaScript의 선택이 모두 중요합니다. 1) Python의 개발 환경에는 Pycharm, Jupyternotebook 및 Anaconda가 포함되어 있으며 데이터 과학 및 빠른 프로토 타이핑에 적합합니다. 2) JavaScript의 개발 환경에는 Node.js, VScode 및 Webpack이 포함되어 있으며 프론트 엔드 및 백엔드 개발에 적합합니다. 프로젝트 요구에 따라 올바른 도구를 선택하면 개발 효율성과 프로젝트 성공률이 향상 될 수 있습니다.

JavaScript가 C로 작성 되었습니까? 증거를 검토합니다JavaScript가 C로 작성 되었습니까? 증거를 검토합니다Apr 25, 2025 am 12:15 AM

예, JavaScript의 엔진 코어는 C로 작성되었습니다. 1) C 언어는 효율적인 성능과 기본 제어를 제공하며, 이는 JavaScript 엔진 개발에 적합합니다. 2) V8 엔진을 예를 들어, 핵심은 C로 작성되며 C의 효율성 및 객체 지향적 특성을 결합하여 C로 작성됩니다.

JavaScript의 역할 : 웹 대화식 및 역동적 인 웹JavaScript의 역할 : 웹 대화식 및 역동적 인 웹Apr 24, 2025 am 12:12 AM

JavaScript는 웹 페이지의 상호 작용과 역학을 향상시키기 때문에 현대 웹 사이트의 핵심입니다. 1) 페이지를 새로 고치지 않고 콘텐츠를 변경할 수 있습니다. 2) Domapi를 통해 웹 페이지 조작, 3) 애니메이션 및 드래그 앤 드롭과 같은 복잡한 대화식 효과를 지원합니다. 4) 성능 및 모범 사례를 최적화하여 사용자 경험을 향상시킵니다.

C 및 JavaScript : 연결이 설명되었습니다C 및 JavaScript : 연결이 설명되었습니다Apr 23, 2025 am 12:07 AM

C 및 JavaScript는 WebAssembly를 통한 상호 운용성을 달성합니다. 1) C 코드는 WebAssembly 모듈로 컴파일되어 컴퓨팅 전력을 향상시키기 위해 JavaScript 환경에 도입됩니다. 2) 게임 개발에서 C는 물리 엔진 및 그래픽 렌더링을 처리하며 JavaScript는 게임 로직 및 사용자 인터페이스를 담당합니다.

웹 사이트에서 앱으로 : 다양한 JavaScript 애플리케이션웹 사이트에서 앱으로 : 다양한 JavaScript 애플리케이션Apr 22, 2025 am 12:02 AM

JavaScript는 웹 사이트, 모바일 응용 프로그램, 데스크탑 응용 프로그램 및 서버 측 프로그래밍에서 널리 사용됩니다. 1) 웹 사이트 개발에서 JavaScript는 HTML 및 CSS와 함께 DOM을 운영하여 동적 효과를 달성하고 jQuery 및 React와 같은 프레임 워크를 지원합니다. 2) 반응 및 이온 성을 통해 JavaScript는 크로스 플랫폼 모바일 애플리케이션을 개발하는 데 사용됩니다. 3) 전자 프레임 워크를 사용하면 JavaScript가 데스크탑 애플리케이션을 구축 할 수 있습니다. 4) node.js는 JavaScript가 서버 측에서 실행되도록하고 동시 요청이 높은 높은 요청을 지원합니다.

Python vs. JavaScript : 사용 사례 및 응용 프로그램 비교Python vs. JavaScript : 사용 사례 및 응용 프로그램 비교Apr 21, 2025 am 12:01 AM

Python은 데이터 과학 및 자동화에 더 적합한 반면 JavaScript는 프론트 엔드 및 풀 스택 개발에 더 적합합니다. 1. Python은 데이터 처리 및 모델링을 위해 Numpy 및 Pandas와 같은 라이브러리를 사용하여 데이터 과학 및 기계 학습에서 잘 수행됩니다. 2. 파이썬은 간결하고 자동화 및 스크립팅이 효율적입니다. 3. JavaScript는 프론트 엔드 개발에 없어서는 안될 것이며 동적 웹 페이지 및 단일 페이지 응용 프로그램을 구축하는 데 사용됩니다. 4. JavaScript는 Node.js를 통해 백엔드 개발에 역할을하며 전체 스택 개발을 지원합니다.

JavaScript 통역사 및 컴파일러에서 C/C의 역할JavaScript 통역사 및 컴파일러에서 C/C의 역할Apr 20, 2025 am 12:01 AM

C와 C는 주로 통역사와 JIT 컴파일러를 구현하는 데 사용되는 JavaScript 엔진에서 중요한 역할을합니다. 1) C는 JavaScript 소스 코드를 구문 분석하고 추상 구문 트리를 생성하는 데 사용됩니다. 2) C는 바이트 코드 생성 및 실행을 담당합니다. 3) C는 JIT 컴파일러를 구현하고 런타임에 핫스팟 코드를 최적화하고 컴파일하며 JavaScript의 실행 효율을 크게 향상시킵니다.

자바 스크립트 행동 : 실제 예제 및 프로젝트자바 스크립트 행동 : 실제 예제 및 프로젝트Apr 19, 2025 am 12:13 AM

실제 세계에서 JavaScript의 응용 프로그램에는 프론트 엔드 및 백엔드 개발이 포함됩니다. 1) DOM 운영 및 이벤트 처리와 관련된 TODO 목록 응용 프로그램을 구축하여 프론트 엔드 애플리케이션을 표시합니다. 2) Node.js를 통해 RESTFULAPI를 구축하고 Express를 통해 백엔드 응용 프로그램을 시연하십시오.

See all articles

핫 AI 도구

Undresser.AI Undress

Undresser.AI Undress

사실적인 누드 사진을 만들기 위한 AI 기반 앱

AI Clothes Remover

AI Clothes Remover

사진에서 옷을 제거하는 온라인 AI 도구입니다.

Undress AI Tool

Undress AI Tool

무료로 이미지를 벗다

Clothoff.io

Clothoff.io

AI 옷 제거제

Video Face Swap

Video Face Swap

완전히 무료인 AI 얼굴 교환 도구를 사용하여 모든 비디오의 얼굴을 쉽게 바꾸세요!

뜨거운 도구

VSCode Windows 64비트 다운로드

VSCode Windows 64비트 다운로드

Microsoft에서 출시한 강력한 무료 IDE 편집기

MinGW - Windows용 미니멀리스트 GNU

MinGW - Windows용 미니멀리스트 GNU

이 프로젝트는 osdn.net/projects/mingw로 마이그레이션되는 중입니다. 계속해서 그곳에서 우리를 팔로우할 수 있습니다. MinGW: GCC(GNU Compiler Collection)의 기본 Windows 포트로, 기본 Windows 애플리케이션을 구축하기 위한 무료 배포 가능 가져오기 라이브러리 및 헤더 파일로 C99 기능을 지원하는 MSVC 런타임에 대한 확장이 포함되어 있습니다. 모든 MinGW 소프트웨어는 64비트 Windows 플랫폼에서 실행될 수 있습니다.

에디트플러스 중국어 크랙 버전

에디트플러스 중국어 크랙 버전

작은 크기, 구문 강조, 코드 프롬프트 기능을 지원하지 않음

Eclipse용 SAP NetWeaver 서버 어댑터

Eclipse용 SAP NetWeaver 서버 어댑터

Eclipse를 SAP NetWeaver 애플리케이션 서버와 통합합니다.

Dreamweaver Mac版

Dreamweaver Mac版

시각적 웹 개발 도구