RMagick (ImageMagick) зависает при запуске в разветвленном процессе - PullRequest
3 голосов
/ 07 июля 2011

В экземпляре Rails 3.0.0 с Ruby 1.8.7 я пытаюсь перенести некоторые задачи обработки изображений с помощью RMagick (2.13.0) в отдельный процесс с использованием fork ().Однако дочерний процесс, в котором обработка изображений выполняется ВСЕГДА, зависает при вызове Magick :: Image.new, Magick :: Image.crop или Magick :: Image.composite.

При "зависании" Iозначает, что процесс просто застревает в этой конкретной команде;он не проходит эту строку и не выдает никаких исключений, и мне приходится вручную убивать процесс.Кроме того, дочерний процесс, кажется, не использует дополнительную память, когда застревает, что действительно заставляет меня задуматься о том, что он на самом деле делает.

Соответствующий код выглядит примерно так: (это неактуальный код!)

def trigger_fork
    img_content = get_image_content
    p = Process.fork { process_image(img_content) }
    Process.detach(p)
    redirect_to root_path
end

def process_image(img_content)
    img = Magick::Image.from_blob(img_content)  # this works fine!
    composite_image(img)
end

def composite_image(img)
    # child process gets stuck here!!
    dummy = Magick::Image.new(100,100) { self.background_color = "white" }

    img.composite(dummy, 0, 0, Magick::XorCompositeOp)
end

Если я заменим Magick::Image.new на img.crop, процесс также будет зависать!Интересно то, что если я отключаю разветвление и просто запускаю функцию process_image в том же процессе, что и вызывающая программа, все работает просто отлично!

Я искал по всему Интернету, но все равно не могу понятьпочему это происходит.Буду очень признателен, если кто-нибудь сможет мне помочь с этой проблемой.Спасибо!

  • Дополнительная информация: я использую WEBrick и MySQL для своей среды разработки

Ответы [ 2 ]

1 голос
/ 12 июля 2011

Если это происходит в процессе Rails, я думаю, это связано с тем, как Ruby и RMagick обрабатывают память. RMagick известен тем, что имел проблемы с памятью, а Rails известен тем, что не дружелюбно пытался делать подобные вещи.

Я бы настоятельно рекомендовал фоновую работу для этого. Если у вас есть временные ограничения, просто добавьте достаточное количество работников и ресурсов, чтобы они своевременно обрабатывались. Ваши проблемы с этим подходом не прекратятся ни разу / если вы решите эту проблему.

0 голосов
/ 23 августа 2013

У меня была та же проблема со сценарием водяных знаков.

Я генерировал изображение водяного знака, а затем создал несколько процессов, которые накладывали водяной знак на другие изображения.Рабочие застряли при звонке composite.Перемещение кода генерации водяных знаков в блок fork исправило это для меня.

Как правило, старайтесь, чтобы код, связанный с RMagick, содержался в одном процессе.

Примечание:эта ошибка только укусила меня, когда я переместил код в производство, на моей рабочей станции все работало нормально

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...