【发布时间】:2011-01-22 16:49:33
【问题描述】:
我正在尝试使用 IO.popen 将(使用 .puts 方法)和获取(使用 .gets 方法)消息从一个进程发送到其子进程。
我不是很有经验,我有一个问题。有以下代码,我有一个错误,因为无法在封闭的流中写入。
class Interface
def initialize(path)
@sub_process = IO.popen(path, 'w+')
end
def start!
if ok?
@sub_process.puts 'Hello', 'my name is ...'
# and more...
end
end
protected
def ok?
is_ready?(@sub_process) && is_cool?(@sub_process)
end
def is_ready?(sub_process)
reply = process_command(sub_process, 'are u ready?')
reply.chomp.match(/yes_i_am_ready$/)
end
def is_cool?(sub_process)
reply = process_command(sub_process, 'are u cool?')
reply.chomp.match(/yes_i_am_cool$/)
end
def process_command(sub_process, command)
rdr = Thread.new { sub_process.read } # alternative: io.readlines
sub_process.puts "#{command}"
sub_process.close_write
rdr.value # joins and fetches the result
end
end
a = Interface.new("./program")
a.start!
(...) in `write': not opens for writing (IOError)
正如我们所见,这个错误发生在 is_cool?测试(解释:http://ruby-doc.org/core/classes/IO.html#M002289)。
但如果我尝试在 process_command 方法中注释该行:
# sub_process.close_write
脚本似乎在休眠...无限:s
我相信不可能再次打开已关闭的流。而且我无法创建我的程序“./program”的另一个 IO.popen 实例,因为它需要在开始时使用一些命令(比如“你准备好了吗?”和“你酷吗?”)进行初始化,之前我使用它(通过像简单讨论一样发送和接收消息)。
为了解决这个问题,我可以对当前代码进行哪些更改?
编辑:换句话说,我想建立这样的通信(根据给定的协议):
Parent message: Child answer:
-------------- ------------
'are u ready?' 'yes_i_am_ready'
'are u cool?' 'yes_i_am_cool'
'Hello' 'foo'
'my name is ...' 'bar'
非常感谢您的帮助。
【问题讨论】:
-
如果将
sub_process.close_write替换为sub_process.flush会发生什么? -
父进程似乎无限等待。如果我使用 Timeout::timeout(5) { ... },则退出 Timeout::Error。
标签: ruby process multithreading io popen