我正在使用Open3的popen2与简单的C ++程序的iostream进行交互。我的理解是std :: cin和std :: cout是独立的,但是我的popen2块的IO对象读/写调用的顺序似乎有所不同。我的C ++程序是:
int main(int argc, char** argv) {
std::string input;
std::cout<<"EXECUTE TASK"<<std::endl;
std::cin>>input;
std::cout<<"END"<<std::endl;
}
我的红宝石脚本是:
require 'open3'
expected_string = "EXECUTE TASK"
Open3.popen2('~/Sandbox/a.out') { |stdin, stdout|
stdin.write('\n')
stdin.close
results = stdout.readlines
puts results
}
以上工作正常,但如果我在stdout.readlines
之前移动stdin.close
,则ruby脚本将挂起。我的意图是如果C ++程序首先将expected_string
写入标准输出,则有条件地将\ n写入stdin,但是在执行readlines之前我被迫关闭stdin流。就像我说的那样,我的理解是两个流是独立的,popen2返回的文件描述符看起来也是独立的,为什么这个顺序很重要?
感谢任何帮助。感谢。
我想要完成的全部范围的解决方案(有人可能会发现这有用):
int main(int argc, char** argv) {
std::string input;
std::cout<<"1"<<std::endl;
std::cout<<"2"<<std::endl;
std::cout<<"3"<<std::endl;
std::cout<<"4"<<std::endl;
std::cout<<"5"<<std::endl;
std::cout<<"EXECUTE TASK"<<std::endl;
std::cout.flush();
std::cin>>input;
std::cout<<"END"<<std::endl;
}
require 'open3'
expected_string = "EXECUTE TASK"
Open3.popen2('~/Sandbox/a.out') { |stdin, stdout|
found = false
begin
while(result = stdout.readline)
puts result
if(result.include?(expected_string))
found = true
break
end
end
rescue
raise "Exception caught while reading lines"
end
stdin.write('\n')
stdin.close
}
答案 0 :(得分:1)
看起来像死锁:
IO::readlines
,在读取整个流之前不会返回。 您可能需要调用IO::readline
,它会在收到每行时返回,或重新排序这两个脚本,以便没有死锁。
答案 1 :(得分:0)
在您希望通讯员采取行动后,您很可能只需要stdout.flush
。
由于#popen
设置的管道不是tty,因此不会默认为线路缓冲。它会阻止缓冲。您需要通过在“记录”边界上调用#flush
来强制您的流以数据报方式运行。
另外,请参阅IO#sync=
了解自动刷新所有I / O的方法。