首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >为什么stdin.readline不读到最后

为什么stdin.readline不读到最后
EN

Stack Overflow用户
提问于 2019-05-05 19:51:50
回答 1查看 160关注 0票数 0

我对python很陌生,我尝试从其他python脚本向一个子进程发送信息,但是在主进程停止发送之前,子进程不会读取任何信息。

我试图发送以“\n”结尾的新行和行。我知道我的子进程被阻塞,直到流结束,但是如果我发送\n或直接stdin.write ('\ n'),它应该正确读取,但它没有

主要进程:

代码语言:javascript
复制
import subprocess
import time

child = subprocess.Popen("python3 example.py", shell=True, stdin=subprocess.PIPE, universal_newlines=True)
s = "this is the message"
print("MAIN:The child pid is: " + str(child.pid))
for i in range(0, 5):
    print("MAIN:iteration send:" + str(i))
    msg = s + "-" + str(i) + "\n"
    child.stdin.writelines(msg)
    time.sleep(1)
child.kill()

子进程:

代码语言:javascript
复制
import time
from sys import stdin

while True:
    try:
        print("CHILD:before read")
        s = stdin.readline()
        print("CHILD:after read")
        print("CHILD:message received is:" + s)
    except EOFError as err:
        print("M_READ_ERROR")
    time.sleep(1)

我的输出是

代码语言:javascript
复制
MAIN:The child pid is: 18041
MAIN:iteration send:0
CHILD:before read
MAIN:iteration send:1
MAIN:iteration send:2
MAIN:iteration send:3
MAIN:iteration send:4
CHILD:after read
CHILD:message received id:this is the message-0

但我期待的是:

代码语言:javascript
复制
MAIN:The child pid is: 18041
MAIN:iteration send:0
CHILD:before read
CHILD:after read
CHILD:message received id:this is the message-0
MAIN:iteration send:1
CHILD:before read
CHILD:after read
CHILD:message received id:this is the message-1
MAIN:iteration send:2
CHILD:before read
CHILD:after read
CHILD:message received id:this is the message-2
MAIN:iteration send:3
CHILD:before read
CHILD:after read
CHILD:message received id:this is the message-3
MAIN:iteration send:4
CHILD:before read
CHILD:after read
CHILD:message received id:this is the message-4
EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2019-05-05 20:04:30

管道使用的是系统的默认缓冲区大小(io.DEFAULT_BUFFER_SIZE)。读取器被阻塞,因为缓冲区尚未填充,因此流中没有可用读取的指示符。

要解决这个问题,您需要控制缓冲。有两种方法。

首先,您可以在每次写完之后进行显式刷新。

代码语言:javascript
复制
child.stdin.writelines(msg)
child.stdin.flush()

这有效地实现了行缓冲,但在您自己的代码中。

其次,您可以在普罗()调用中通过传递bufsize kwarg来选择缓冲模式。大于1的正修改设置了该值的缓冲区大小,这意味着当缓冲区被填充时,您的读者将得到随时准备的信号。但也有一些特殊情况:

  • 0表示未缓冲,因此每一次写入都会立即刷新;
  • 1表示行缓冲,这是一种特殊情况,在用户空间中,io库扫描新行并在其后面刷新。

您可以通过bufsize=1在换行符后强制刷新。在python3中,这取决于universal_newlines=True,但是已经有了。

票数 2
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/55995818

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档