在一个带有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只在我将代码转移到生产环境时咬我,在我的工作站上一切正常