我正在使用 Celluloid创建作业处理服务器。我有一个 pool从 beanstalkd 队列中获取任务并使用 Process.spawn
调用执行大量工作的 PHP 脚本来处理它的工作人员。
这是我执行 PHP 命令的方式:
rout, wout = ::IO.pipe
pid = Process.spawn(cmd, :err=> :out, :out => wout)
_, exit_status = Process.wait2(pid)
wout.close
output = rout.readlines.join("\n")
这在“大部分”时间都有效。我已经对数百个工作进行了测试,一切都很好。但是当我将其投入生产时,一些 PHP 命令无限期挂起。
如果我终止挂起的进程并查看 PHP 命令写入的日志文件,最后的日志消息是任意数量的看似随机的不显眼事件(也就是说,我无法辨别进程在之前进行了多远的任何模式它挂起)。
处理作业的 PHP 脚本已在生产中使用了几个月,但在 cron 上执行。因此,唯一发生变化的是它们正在从这个新的作业处理器中执行。
我是不是用错了方法? Ruby 是否以某种方式暂停/休眠进程或类似的东西——我是否没有正确读取输出并且正在阻止它?
--- 编辑 ---
我切换到使用反引号运算符来执行命令(阻塞并不重要,因为 Celluloid Actor 是异步的):
output = `#{cmd}`
pid = $?.pid
exit_status = $?.exitstatus
到目前为止,一切正常。使用反引号有何不同?
最佳答案
我认为这与 Ruby 启动子进程并随后与它们交互的方式有关。
我自己对此了解不多,但我找到了 this对于理解生成子进程的不同方式以及何时使用它们非常有用。
使用 Celluloid 有点远,我认为这与您遇到的问题无关。
关于ruby - Process.spawn挂起,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/16187451/