2011-07-07 47 views
3

在使用Ruby 1.8.7的Rails 3.0.0实例中,我试图使用RMagick(2.13.0)将一些图像处理任务推送到单独的进程中叉子()。但是,图像处理发生的子进程始终会在调用Magick :: Image.new,Magick :: Image.crop或Magick :: Image.composite时挂起。 “挂”我的意思是这个过程只是停留在那个特定的命令上;它既没有超过那条线也没有抛出任何异常,我必须手动杀死这个进程。另外,子进程在卡住时似乎没有使用任何额外的内存,这真的让我想知道它实际上在做什么。RMagick(ImageMagick)在分叉进程中运行时挂起

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

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.newimg.crop,过程中也将挂起!有趣的部分是,如果我禁用分叉,并在与调用方相同的进程中运行process_image函数,则一切正常!

我在互联网上搜索了所有内容,但仍然无法弄清楚为什么会发生这种情况。如果有人能帮助我解决这个问题,我会非常感激。谢谢!

  • 其他详细信息:我使用的WEBrick和MySQL我的开发环境
+0

没有,但是这似乎是具体到了Rails + RMagick组合存在问题;我只是想了解它为什么会发生 –

+0

分叉不是Rails中的最佳方式,取决于服务器。在Rails中搜索后台作业,有很多选择。 –

+0

我有我的理由:后台作业只能随时处理1个请求;我希望用户的请求在提交作业后立即开始。线程是另一种选择;我会尝试它并在此处报告结果。 –

回答

1

如果这是在Rails的过程中发生的,我猜想,这有什么做的方式Ruby和RMagick处理内存。 RMagick以存在内存问题而闻名,而Rails因尝试执行这样的事情而不友善而出名。

我强烈建议为此做一个后台工作。如果您有时间限制,只需添加足够的工作人员和资源,以便及时处理。如果你解决了这个问题,你的问题就不会停止。

0

我对水印脚本有同样的问题。

我正在生成水印图像,然后分叉几个过程,将水印合成到其他图像上。致电composite时,工人被卡住了。将水印生成代码移动到fork块中为我解决了问题。

作为一个经验法则,试着保持处理包含在单个进程中的RMagick的代码。

注:该错误只咬了我,当我提出的代码到生产,一切都工作得很好我的工作站