ruby on rails - RMagick (ImageMagick)在fork进程中运行时会挂起



在一个带有Ruby 1.8.7的Rails 3.0.0实例上,我尝试使用RMagick(2.13.0)将一些图像处理任务推送到使用fork()的单独进程中。但是,当Magick:: image时,进行图像处理的子进程总是挂起。新的魔法:形象。

我说的"挂起"是指进程在那个特定的命令上卡住了;它既没有越过这条线,也没有抛出任何异常,我必须手动终止进程。此外,当子进程卡住时,它似乎没有使用任何额外的内存,这真的让我想知道它到底在做什么。

相关代码看起来有点像这样:(这不是实际的代码!)

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

如果我用img.crop替换Magick::Image.new,这个过程也会挂起!有趣的部分是,如果我禁用fork并在与调用者相同的进程中运行process_image函数,那么一切都会正常工作!

我搜遍了整个互联网,但仍然不明白为什么会发生这种情况。如果有人能帮我解决这个问题,我将非常感激。谢谢!

  • 附加细节:我使用WEBrick和MySQL为我的开发环境

如果这发生在Rails进程中,我猜它与Ruby和RMagick处理内存的方式有关。RMagick是出了名的内存问题,而Rails是出了名的不友好。

我强烈推荐这方面的后台工作。如果您有时间限制,只需添加足够的工人和资源,以便及时处理即可。如果你解决了这个问题,你的问题就不会停止了。

我在使用水印脚本时遇到了同样的问题。

我正在生成水印图像,然后在其他图像上合成水印的几个过程。工人们在呼叫composite时被卡住了。将水印生成代码移动到fork块中为我修复了它。

作为经验法则,尽量将处理RMagick的代码包含在单个进程中。

注意:这个bug只在我将代码转移到生产环境时咬我,在我的工作站上一切正常

最新更新