node.js - 生成1000个图像,导致重负载

时间:2015-03-15 10:39:49

标签: node.js imagick graphicsmagick

我是node.js的新手。 我想用imagick,gmagick生成一些图像用于测试目的。 图像的名称应为000001.jpg至0x.jpg。 对于后来的测试,我需要大约50.000张图像。

var async = require('async');
var gm = require('gm')
            .subClass({ imageMagick: true }); // Enable ImageMagick integration.


var number = parseInt(process.argv[2]) || 20;
console.log("Generating " + number + " images");

var pad = "000000";
var img_names = [];
for (i=1;i<=number;i++) {
    var str = "" + i;
    var padded_str = pad.substring(0, pad.length - str.length) + str;
    img_names.push(padded_str+".jpg");
}

async.forEach(img_names, function (item, callback){ 
    console.log(item); // print the key
    gm(800, 600, "#ddff99f3").font("Helvetica.ttf", 80)
    .drawText(150, 300, "# "+item)
    .write("./"+item, function (err) {
      if(err) {
        console.error(err);
        process.exit(1);
      }
    }); 
    callback(); // tell async that the iterator has completed

}, function(err) {
    console.log('iterating done');
});

问题在于,当使用更高的图像时,ubuntu机器会启动大量的“转换”进程并进入负载状态。

有人能指出我正确的方向吗? 亲切的问候,罗伯特

1 个答案:

答案 0 :(得分:4)

您需要将callback()函数移动到write函数的回调中,因为迭代刚刚分叉gmagick,并且实际上并没有等待它完成。当它完成时,它会调用自己的回调 - 这是迭代的结束,所以它应该调用forEach()函数的回调。

如上所述移动callback()将阻止async.forEach()直到gm()功能完成。

如果您有多核机器,您可以并行运行此功能,每个核心/超线程大约有一个工作进程是明智的默认值。为eachLimit()交换forEach并将并行度设置为8:

async.eachLimit(img_names, 8, function (item, callback){ 
    console.log(item); // print the key
    gm(800, 600, "#ddff99f3").font("Helvetica.ttf", 80)
    .drawText(150, 300, "# "+item)
    .write("./"+item, function (err) {
      if(err) {
        console.error(err);
        process.exit(1);
      }
      callback(); // tell async that the iterator has completed
    }); 

}, function(err) {
    console.log('iterating done');
});