【问题标题】:Node and talking to child processes节点并与子进程交谈
【发布时间】:2020-10-06 04:10:35
【问题描述】:

上下文

编写串行监视器来收听 Arduino 并不难。使用端口名称和波特率的命令行参数启动它很简单,因此从 Node 配置和启动监视器并不复杂:

child_process.exec("./monitor COM6 115200");

这个问题涉及execforkspawn,它们很相似,但我还没有掌握其中的微妙之处。除了使用参数启动之外,我还需要

  • 捕获输出,以便在窗口中显示它
  • 杀死子进程
    • 使用不同的参数重新启动
    • 刷 Arduino,然后在重启后重新启动

我使用 netcore 编写了一个控制台应用程序,它接受两个命令行参数,然后连接并侦听,回显到它的 stdout。我选择了 netcore,因为它可以在所有三个平台上运行。

问题

execforkspawn 应该使用哪个?

如何杀死子进程?

如何捕获子进程的stdout

Node 文档谈到了 kill method on a subprocess object。该页面上的示例代码暗示该对象由spawn 返回,但是当我使用 spawn 时,它似乎静默失败。那或者它正在工作,但我不知道我在做什么,这就是我提出这个问题的原因。

所有这些节点代码都将成为 VSCode 扩展的一部分,所以如果你也知道那些我想将标准输出通过管道传输到 VSCode 输出通道,如果可能的话。

【问题讨论】:

    标签: node.js vscode-extensions child-process kill


    【解决方案1】:

    通过 spawn,您可以收听标准输出。

    然后用 kill() 杀死进程

    来自官方 NodeJS 文档:

    const { spawn } = require('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}`);
    });
    
    // some logic
    ls.kill()
    

    编辑:一个更具体的例子:

    // server.js --------------
    const http = require('http');
    
    const server = http.createServer(
        (function() {
            console.log('Initializing server');
            return (req, res) => {
                res.end('Hello World');
            };
        })()
    );
    
    server.listen(8080, () => console.log('Server is up on port ' + 8080));
    
    // spawn.js --------------
    const { spawn } = require('child_process');
    
    const child = spawn('node', ['./server.js']);
    
    child.stdout.on('data', data => console.log(data.toString()));
    
    child.stderr.on('data', data => console.log('Error: ' + data));
    
    child.on('close', code => console.log(`Process ended with code ${code}`));
    
    child.on('error', err => console.log(err));
    
    setTimeout(() => child.kill(), 2000);
    
    

    【讨论】:

    • 这看起来很不错。在我可以尝试之前,我还有其他代码要整理,但我认为你已经给了我继续我的项目所需的东西。或许可以稍微解释一下exec、fork和spawn之间的概念和差异,特别是预期用途的差异,以回答为什么有三种方式启动进程的问题。
    • @PeterWone 绝对!据我了解,由于所有这些产生子进程,差异很小,但是它们以不同的方式进行。用例可能取决于操作系统。 execFile 在 UNIX 系统中非常方便,默认情况下它不会生成 shell(在没有 shell 的情况下运行可执行文件)。在 Windows 上,使用 exec 作为 .bat 和 .cmd 文件在没有终端的情况下无法执行可能是一个更好的主意。 Spawn 和 Fork 类似,只是 fork 会产生新的 Node 进程,并且有一个额外的通信通道,允许在父子节点之间发送消息。
    • @PeterWone 根据指定的命令生成和分叉生成进程并传递提供的参数。
    猜你喜欢
    • 2011-09-22
    • 1970-01-01
    • 1970-01-01
    • 2012-05-10
    • 2011-11-08
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多