当我启动一个新的分叉进程时,NodeJS分叉进程正在减慢所有其他分叉进程的速度



我有一个NodeJS程序,它使用ImageMagick从数据库中的一些文本创建图像。该程序是使用从我的NodeJs服务器上午餐的

import childProcess from 'child_process';
let args = [':imageId', '--max_old_space_size=4096'];
childProcess.fork('createImage.js', args);

创建图像的过程相当缓慢,在我的本地机器上,对于尺寸为114x84cm的单个图像,可能需要5-6分钟。

我将尝试解释程序生命周期中正在发生的事情。

所以,我有一个运行在进程MyServer上的服务器,当有人请求映像MyServer时,它会分叉一个新进程。

新进程ImageCreator1有一个来自promise的循环,并将等待,直到所有问题都得到解决。每个承诺都会使用ImageMagick创建大图像的一部分

在我的活动监视器中,我可以看到有一些正在运行的进程

Process Name   |  %CPU
MyServer       -  0.3
ImageCreator1  -  30.0
convert        -  0.1
convert        -  0.1
convert        -  0.2
convert        -  0.1

此外,我可以看到ImageCreator1运行异步4-5ImageMagick转换进程来创建所有这些所需的小映像。

这一切大约需要5分钟。创造大形象。

所以当我启动两个ImageCreators时,时间增加到9分钟。

Process Name   |  %CPU
MyServer       -  0.3
ImageCreator1  -  30.0
ImageCreator2  -  40.0
convert        -  0.1
convert        -  0.1
convert        -  0.2
convert        -  0.1
convert        -  0.1
convert        -  0.1
convert        -  0.2
convert        -  0.1

如果我启动CCD_ 11或CCD_。我在想,当我开始一个新的过程时,这个过程是否能在5分钟内完成任务。然后,如果我同时开始五个过程,每个过程都必须完成5分钟。但似乎对于每个新的CCD_ 13,所有人的时间都增加了。

我还在学习NodeJs和这个OS的东西,所以如果有人能解释发生了什么,那就太好了。

更新IMAGECREATOR代码!!!

console.time('imageCreator');
process.title = 'imageCreator'+process.argv[2];
const fs = require('fs');
const gm = require('gm').subClass({imageMagick:true});
const Promise = require('bluebird');
var images = [], rows = [];
for(var i = 1; i<=100;i++){
images.push(i);
}
for(var i = 1; i<=10;i++){
rows.push(Promise.reduce(images, function(total, image){
return new Promise(function(resolve, reject) {
gm('xc:rgb('+(image*2)+','+image+','+(image*2)+')')
.in('-units', 'PixelsPerInch')
.in('-size', '100x100')
.in('-density', 300)
.in('-page', '+'+(image-100)*100+'+0')
.toBuffer('miff', function(err, stream){
fs.appendFile(__dirname+'/test'+process.argv[2]+'.miff', stream, function(err){
if(err) reject(err);
else resolve(image);
});
});
});
}));
}

Promise.all(rows).then(function( ) {
console.timeEnd('imageCreator');
});

所以我做了一些测试来找出我的脚本中有什么部分有问题。下面是一个例子,当我在mac上运行这个程序时会发生什么。顺便说一句,我确实重新编译了ImageMagick,所以现在我有了:

Version: ImageMagick 6.9.7-2 Q16 x86_64 2017-01-03 http://www.imagemagick.org
Copyright: © 1999-2017 ImageMagick Studio LLC
License: http://www.imagemagick.org/script/license.php
Features: Cipher DPC Modules 
Delegates (built-in): bzlib freetype jng jpeg ltdl lzma png tiff xml zlib

所以当我在一个终端上运行上面的脚本时,我得到的时间是:

Terminal1 - imageCreator: 7498.438ms - 7.4984380002sec.

但当我同时尝试两个终端时:

Terminal1 - imageCreator: 14632.522ms - 14.632522sec.
Terminal2 - imageCreator: 13734ms - 13.734sec.

正如你所看到的,两者的时间几乎都翻了一番。

我的电脑有:

processor:2.7 GHz Intel Core i5
memory:8 GB 1867 MHz DDR3

所以发生了什么,我想公羊也参与其中,但我不太擅长这种低级的东西,所以如果有人能解释一下,那就太好了。提前谢谢。

执行此代码的计算机有多少CPU核心?当您使用child_process创建新进程时,您正在启动一个新进程——这意味着操作系统调度程序将尝试与父进程并行运行新进程——但这需要多个CPU。

如果你没有多个CPU,那么操作系统调度程序将开始在运行主进程和子进程之间进行交换,并在同一CPU上为它们提供CPU时间,从而不会真正"并行"运行它们,因为在任何给定时间都只执行一条指令。

另一件需要注意的事情是ImageMagick:在多个进程中运行安全吗?

我对ImageMagick不是很熟悉,但根据2009年的这个旧线程(现在可能很不一样),ImageMagick使用自己的线程:因此在多个进程中同时运行它不会导致任何加速。

希望能有所帮助!

最新更新