【问题标题】:How can i thread image processing in NodeJS?如何在 NodeJS 中进行线程图像处理?
【发布时间】:2013-10-11 06:13:34
【问题描述】:

我正在 NodeJS 上编写一个图像处理 Web 服务,基本上我需要弄清楚如何使实际的图像处理线程化。当我通过 Apache AB 对其进行测试时,NodeJS 仅使用一个内核并停滞不前,我肯定在这里做错了。如何重新设计这个简单的应用程序以利用服务器 CPU 上的多个内核。

我缩小了所有输入过滤并简化了图像处理功能,让您了解应用程序结构而不是长代码位。

在 app.js 中

app.get('/generate/:q', function(req, res){
    var textString = req.params.q;
    res.setHeader("Content-Type", "image/png");
    res.end(generator.s());
});

在 generate.js 中

var Canvas = require('canvas')
  , Font = Canvas.Font
  , fs = require('fs')
  , path = require("path")
  , plate = new Canvas.Image;

//To keep plate in RAM between requests.
fs.readFile(__dirname + '/plates/dhw132.png', function(err, squid){
    if (err) throw err;
    plate.src = squid;
});

exports.s = function () {
    canvas = new Canvas(731,1024);
    ctx = canvas.getContext('2d');
    ctx.drawImage(plate, 0, 0, plate.width, plate.height);
    return canvas.toBuffer();
}

如何重写它以使 generator.s() 线程化?

【问题讨论】:

  • Node.js 是单线程的。在 NodeJs 中没有一种简单的方法可以做到这一点。 stackoverflow.com/questions/10773564/…
  • 是的,由于 Node 处理请求的方式,我意识到这一点,但我仍然无法用一种简单的方法来使这个可执行文件在不同的内核中运行,我阅读了有关子进程分叉的信息,但似乎没有简单的方法可以将实际的板一次读入内存,然后将 canvas 函数生成到一个进程中,该进程在不同线程中引用文件来执行。
  • 只有一个线程。最简单的方法是在每个进程中加载​​图像。如您所见,数据处理不一定非常适合 NodeJ。它最适合小型异步任务。
  • 将尝试并进行基准测试,目前看起来像这样HTOP
  • 当然也要尽可能使用异步文件操作。

标签: multithreading node.js image-processing asynchronous express


【解决方案1】:

节点当然是单线程,但需要多线程是一个非常有效的用例。我知道有两种方法。

为什么不使用集群。您将获得可配置数量的进程/线程,默认情况下是您机器上的 CPU 数量。集群本质上是跨进程对您的应用程序进行负载平衡,并透明地处理共享单个侦听 http 端口的那些进程。

http://nodejs.org/api/cluster.html

这里也有一个包装器:https://github.com/dpweb/cluster-node

另一种选择,您可以直接分叉该过程,这是一个使用 lame 将上传的文件转换为 mp3 的示例。对于您的情况,您可以将所有图像处理封装在一个单独的应用程序中,因此 clusters 选项可能这样做会更干净。

app.post('/process', function(req, res){
        var f = req.files.filen;
        fs.rename(f.path, f.name, function(err) {
            if (err){
                fs.unlink(f.name, ef);
                throw err;
                return;
            }
            fs.unlink(f.path, function() {
                    var ext = "." + req.body.extn;

                    require('child_process').exec("lame "+f.name, function(err, out, er) {
                            var nfn = f.name + '.mp3';
                            res.setHeader('Content-Type', 'application/octet-stream');
                            res.setHeader('Content-disposition', 'attachment; filename='+nfn);
                            res.setHeader("Content-Transfer-Encoding: binary");
                            res.setHeader('Accept-Ranges: bytes');

                            var size = fs.statSync(nfn).size;
                            console.log(size, f.name, nfn)
                            res.setHeader('Content-Length', size);
                            fs.createReadStream(nfn).pipe(res);
                            fs.unlink(nfn, ef); fs.unlink(f.name, ef);
                    })
            })
        })
})

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2014-11-12
    • 2021-12-23
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多