RMagick (ImageMagick) 在分叉进程中运行时挂起
在带有 Ruby 1.8.7 的 Rails 3.0.0 实例上,我尝试使用 fork() 将使用 RMagick (2.13.0) 的一些图像处理任务推送到一个单独的进程中。但是,当调用 Magick::Image.new、Magick::Image.crop 或 Magick::Image.composite 时,进行图像处理的子进程始终挂起。
我所说的“挂起”是指进程只是卡在那个特定的命令上;它既不会越过该行,也不会引发任何异常,我必须手动终止该进程。此外,子进程在卡住时似乎没有使用任何额外的内存,这确实让我想知道它实际上在做什么。
相关代码看起来有点像这样:(这不是实际的代码!)
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
,进程也会挂起!有趣的是,如果我禁用分叉并仅在与调用者相同的进程中运行 process_image 函数,则一切正常!
我在互联网上进行了搜索,但仍然无法弄清楚为什么会发生这种情况。如果有人能帮助我解决这个问题,我将非常感激。谢谢!
- 其他细节:我正在使用 WEBrick 和 MySQL 作为我的开发环境
On an instance of Rails 3.0.0 with Ruby 1.8.7, I'm trying to push some image processing tasks using RMagick (2.13.0) into a separate process using fork(). However, the child process in which the image processing takes place ALWAYS hangs when Magick::Image.new, Magick::Image.crop, or Magick::Image.composite is called.
By "hanging" I mean the process just gets stuck at that particular command; it neither gets past that line nor throws any exception, and I have to manually kill the process. In addition, the child process doesn't seem to be using any additional memory when it gets stuck, which really makes me wonder what it's actually doing.
The relevant code looks somewhat like this: (this is not the actual code!)
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
If I replace Magick::Image.new
with img.crop
, the process will also hang! The interesting part is that if I disable forking and just run the process_image function in the same process as the caller, everything works just fine!
I've searched all over the Internet, but still can't figure out why this is happening. I'd really appreciate if someone can help me with this problem. Thanks!
- Additional detail: I'm using WEBrick and MySQL for my development environment
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(2)
如果这种情况发生在 Rails 进程中,我猜测这与 Ruby 和 RMagick 处理内存的方式有关。 RMagick 因存在内存问题而闻名,而 Rails 因尝试做此类事情不友好而闻名。
我强烈推荐为此进行后台工作。如果您有时间限制,只需添加足够的工作人员和资源即可及时处理。如果你解决了这个问题,你的这种方法的问题就不会停止。
If this is happening in a Rails process, I would guess that it has something to do with the way Ruby and RMagick handle memory. RMagick is known for having memory issues, and Rails is known for not being friendly to trying to do stuff like this.
I would strongly recommend a background job for this. If you have timing constraints, just add enough workers and resources that they get processed in a timely manner. Your problems with this approach won't stop once/if you solve this problem.
我在水印脚本上遇到了同样的问题。
我正在生成水印图像,然后分叉一些将水印合成到其他图像上的进程。工作人员在调用
composite
时陷入困境。将水印生成代码移动到 fork 块中为我解决了这个问题。根据经验,尽量将处理 RMagick 的代码包含在单个进程中。
注意:当我将代码转移到生产环境时,这个错误只影响了我,在我的工作站上一切正常
I've had the same issue with a watermarking script.
I was generating the watermark image, then forking a few processes that composited the watermark over other images. The workers got stuck when calling
composite
. Moving the watermark generation code into thefork
block fixed it for me.As a rule of thumb, try to keep the code dealing with RMagick contained to a single process.
Note: this bug only bit me when I moved the code to production, everything worked fine on my workstation