2016-12-30 1 views
1

У меня есть программа NodeJS, которая создает изображение из некоторого текста в моем db, используя ImageMagick. Программа обедал с моего NodeJs сервера с помощьюПроцесс NodeJS fork замедляет все другие разветвленные процессы, когда я начинаю новый

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

Процесс создания изображения довольно медленно она может занимать 5-6min на моей локальной машине для одного изображения с размером 114x84cm.

Я попытаюсь объяснить, что происходит в жизненном цикле программы.

Итак, у меня есть сервер, который работает на процессе MyServer, когда кто-то просит изображение MyServer вилки нового процесса.

Новый процесс ImageCreator1 имеет цикл от обещаний и будет ждать, пока все не будут решены. Каждое обещание создает часть этого большого изображения, используя ImageMagick

В моем мониторе активности я могу видеть, что есть некоторые запущенных процессы

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

Также я могу видеть, что ImageCreator1 работает асинхронные 4-5 ImageMagick процессов конвертированы в создайте все необходимые небольшие изображения.

Все это займет 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 

и если я начинаю ImageCreator3 или ImageCreator4 становится все медленнее и медленнее. Я думал, что когда я начну новый процесс, и если этот процесс завершит работу в течение 5 минут. Затем, если я запускаю одновременность пяти процессов, каждая из них должна заканчиваться на 5 минут. но кажется, что с каждым новым ImageCreator время для всех увеличивается.

Я все еще участвую в обучении с NodeJs и этим OS вещами, поэтому, если кто-то может объяснить, что происходит, было бы здорово.

!!! ОБНОВЛЕНИЕ КОДА ИЗОБРАЖЕНИЙ !!!

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 

так, что происходит, я думаю, баран участвует здесь, но я не очень хорошо с этим материалом низкого уровня, так что если кто-то может объяснить, это было бы здорово. Заранее спасибо.

+0

Скажем, изображение размером 114 см x 84 см не говорит нам много - при «dpi» 1, что будет 9 000 пикселей, но при 600 dpi это будет 3500 000 000 пикселей. –

+0

Извините за поздний ответ, «dpi» изображения составляет 300 точек на дюйм, но разве это действительно важно? Предположим, что если у меня есть процесс запуска и преобразования изображения с 72dpi, и пока этот процесс выполняется, я запускаю еще один, время для обоих увеличивается. Я не знаю, есть ли проблема в ImageMagick или nodejs, нужно выполнить бит больше тестов, я попробую, что общая ссылка @rdegges предложит скомпилировать ImageMagick с помощью --disable-openmp и будет имитировать мою программу nodejs, запущенную без ImageMagick, и опубликует результат. Спасибо за ваш комментарий. – Alex

+0

То, что я имею в виду, 114см x 84см 45 дюймов х 33 дюйма. Таким образом, при 300 dpi ваше изображение будет иметь размер 45 * 300 * 33 * 300 пикселей, т. Е. 133 мегапикселя. Если это цвет, с 3 каналами (RGB) и 16-бит/пиксель, вам нужно будет умножить это на 6, поэтому для каждого изображения потребуется минимум 800 МБ. Возможно, вам следует показать код в «ImageCreator» и посмотреть ограничения RAM на вашем процессе, так как вы можете вывести на диск. –

ответ

1

Сколько процессорных ядер имеет компьютер, на котором выполняется этот код? Когда вы создаете новый процесс с помощью child_process, вы начинаете новый процесс - это означает, что планировщик ОС будет пытаться запустить новый процесс параллельно с вашим родительским процессом, но для этого требуется несколько процессоров.

Если у вас нет нескольких процессоров, произойдет то, что планировщик ОС начнет замену между запуском основного процесса и вашим дочерним процессом и даст каждому из них время процессора на одном процессоре, тем самым не работает их в «параллельном», так как только одна команда будет выполняться в любой момент времени.

Еще одна вещь, которая должна быть осторожной - это ImageMagick: безопасно ли работать в нескольких процессах?

Я не очень хорошо знаком с ImageMagick, но в соответствии с this old thread с 2009 года (это может быть очень хорошо в наши дни), ImageMagick использует собственную потоковую обработку: поэтому одновременное выполнение нескольких процессов не приведет к ускорению.

Надеюсь, что это поможет!