栏目分类:
子分类:
返回
名师互学网用户登录
快速导航关闭
当前搜索
当前分类
子分类
实用工具
热门搜索
名师互学网 > IT > 软件开发 > Web开发 > JavaScript

[Node系统模块系列二] 子进程child_process

JavaScript 更新时间: 发布时间: IT归档 最新发布 模块sitemap 名妆网 法律咨询 聚返吧 英语巴士网 伯小乐 网商动力

[Node系统模块系列二] 子进程child_process

Node是一个单线程多进程的语言,主要是通过I/O操作来进行异步任务处理,I/O越密集Node的优势越能体现,但是CPU密集的任务就会对程序造成阻塞,影响后续程序执行在Node中我们可以采用child_process模块充分利用CPU资源,完成一些耗时耗资源的操作。

先看一段例子,运行下面程序,浏览器执行 http://127.0.0.1:3000/compute 大约每次需要15657.310ms,也就意味下次用户请求需要等待15657.310ms,文末将会采用child_process实现多个进程来处理。

// compute.js

const http = require('http');
const [url, port] = ['127.0.0.1', 3000];

const computation = () => {
    let sum = 0;

    console.info('计算开始');
    console.time('计算耗时');

    for (let i = 0; i < 1e10; i++) {
 sum += i
    };

    console.info('计算结束');
    console.timeEnd('计算耗时');

    return sum;
};

const server = http.createServer((req, res) => {
    if(req.url == '/compute'){
 const sum = computation();

 res.end(`Sum is ${sum}`);
    }

    res.end(`ok`);
});

server.listen(port, url, () => {
    console.log(`server started at http://${url}:${port}`);
});
创建进程 四种方式(异步方式)
  • child_process.spawn()

  • child_process.fork()

  • child_process.exec()

  • child_process.execFile()
spawn

适用于返回大量数据,例如图像处理,二进制数据处理。

请求格式

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

请求参数

  • comman 运行的命令 例如 lh

  • args 命令参数,默认为一个空数组

  • options
    • cwd 子进程的当前工作目录
    • env 环境变量键值对
    • argv0 显式地设置要发给子进程的 argv[0] 的值。 如果未指定,则设为 command
    • stdio | 子进程的 stdio 配置
    • detached 将子进程独立于父进程运行
    • uid 设置该进程用户标识
    • gid 设置该进程的组标识
    • shell 设置为true,不同的shell可以在comman命令中设置为字符安,例如,'ls -lh' 默认为false
  • 返回:
  • 请求示例

    const spawn = require('child_process').spawn;
    const child = spawn('ls', ['-l'], {
        cwd: '/usr', // 指定子进程的工作目录,默认当前目录
    })
    
    console.log(process.pid, child.pid); // 主进程id3243 子进程3244

    执行以上代码后,会在控制台输出主进程id、子进程id,但是子进程的信息并没有在控制台打印,原因是新创建的子进程有自己的stdio流,创建一个父进程和子进程之间传递消息的IPC通道就可实现输出信息。

    方法一 可以让子进程的stdio和当前进程的stdio之间建立管道链接

    const spawn = require('child_process').spawn;
    const child = spawn('ls', ['-l'], {
        cwd: '/usr', // 指定子进程的工作目录,默认当前目录
    })
    
    child.stdout.pipe(process.stdout);

    方法二 父进程子进程之间共用stdio

    options.stdio 选项用于配置子进程与父进程之间建立的管道,值是一个数组['pipe', 'pipe', 'pipe'],为了方便期间可以是一个字符串'pipe'

    • pipe 等同于 'pipe', 'pipe', 'pipe'

    • ignore 等同于 ['ignore', 'ignore', 'ignore']

    • inherit 等同于 [process.stdin, process.stdout, process.stderr] 或 [0,1,2]
    const spawn = require('child_process').spawn;
    const child = spawn('ls', ['-l'], {
        cwd: '/usr', // 指定子进程的工作目录,默认当前目录
        stdio: 'inherit'
    })

    方法三 事件监听

    const spawn = require('child_process').spawn;
    const child = spawn('ls', ['-l'], {
        cwd: '/usr', // 指定子进程的工作目录,默认当前目录
    })
    
    child.stdout.on('data', data => {
        console.log(data.toString());
    });
    exec

    缓存子进程的输出,将子进程的输出以回调函数的形式一次性返回,如果子进程返回的数据过大超过maxBuffer默认值将会导致程序崩溃,也可以设置maxBuffer允许的最大字节数,不建议这样做,exec适合于小量的数据,数据量过大可以采用spawn

    注意: 不要把未经检查的用户输入传入到该函数。 任何包括 shell 元字符的输入都可被用于触发任何命令的执行

    请求格式

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

    请求参数