子进程readline挂起等待EOF

2024-06-28 20:02:49 发布

您现在位置:Python中文网/ 问答频道 /正文

我有一个简单的c++程序,我正试图通过python脚本来执行它。(我对编写脚本非常陌生)而且在通过管道读取输出时遇到问题。从我所看到的,似乎readline()在没有EOF的情况下无法工作,但是我希望能够在程序的中间进行读取,并让脚本对输出的内容做出响应。它不是读取输出,而是挂起 python脚本:

#!/usr/bin/env python
import subprocess
def callRandomNumber():
    print "Running the random guesser"
    rng=subprocess.Popen("./randomNumber", stdin=subprocess.PIPE, stdout=subprocess.PIPE, shell=True)
    i=50
    rng.stdin.write("%d\n" % i)
    output=rng.stdout.readline()
    output=rng.stdout.readline()
callRandomNumber()

c++文件生成一个介于1到100之间的随机数,然后检查用户的猜测,直到他们猜对为止

^{pr2}$

最终的目标是让脚本用二进制搜索来解决问题,但是现在我只想能够在不把它作为文件结尾的情况下读取一行


Tags: 文件程序脚本outputreadline管道stdinstdout
3条回答

作为@Ron Reiter pointed out,您不能使用readline(),因为cout不隐式打印换行符,您需要std::endl或{}。在

对于交互式使用,当您无法更改子程序时,^{} module提供了几种方便的方法(通常是it solves for free: input/output directly from/to terminal (outside of stdin/stdout) and block-buffering issues):

#!/usr/bin/env python
import sys

if sys.version_info[:1] < (3,):
    from pexpect import spawn, EOF # $ pip install pexpect
else:
    from pexpect import spawnu as spawn, EOF # Python 3

child = spawn("./randomNumber") # run command
child.delaybeforesend = 0 
child.logfile_read = sys.stdout # print child output to stdout for debugging
child.expect("enter a number: ") # read the first prompt
lo, hi = 0, 100
while lo <= hi:
    mid = (lo + hi) // 2
    child.sendline(str(mid)) # send number
    index = child.expect([": ", EOF]) # read prompt
    if index == 0: # got prompt
        prompt = child.before
        if "too high" in prompt:
            hi = mid - 1 # guess > num
        elif "too low" in prompt:
            lo = mid + 1 # guess < num
    elif index == 1: # EOF
        assert "Congratulations" in child.before
        child.close()
        break
else:
    print('not found')
    child.terminate()
sys.exit(-child.signalstatus if child.signalstatus else child.exitstatus)

它可以工作,但它是一个二进制搜索,因此(traditionally) there could be bugs。在

下面是一个使用subprocess模块进行比较的类似代码:

^{pr2}$
我确信在C++程序中添加新行会导致读行返回。在

您可能必须显式地关闭stdin,这样子进程将停止挂起,我认为这就是您的代码所发生的情况,这可以通过在终端上运行top并检查randomnumber的状态是否保持休眠,以及它是否在预期的执行时间之后使用了0%CPU来验证。在

简言之,如果您在rng=subprocess(...)调用之后添加rng.stdin.close(),它可能会毫无问题地恢复。另一个选择是做output=rng.communicate(stdin="%d\n" % i),并分别查看output[0]和{},他们分别是{}和{}。您可以在communicatehere上找到信息。在

相关问题 更多 >