Python输入管道缓冲

Python输入管道缓冲,python,pipe,stdin,Python,Pipe,Stdin,我很难理解为什么input没有从子分叉进程立即打印到标准输出。相反,它会等待父级写入其管道(应该映射到sys.stdin)。这与缓冲有关吗 import os import select import sys r, w = os.pipe() pid = os.fork() if pid: try: os.close(r) b = b'' while True: ins, _, _ = select.selec

我很难理解为什么
input
没有从子分叉进程立即打印到标准输出。相反,它会等待父级写入其管道(应该映射到sys.stdin)。这与缓冲有关吗

import os
import select
import sys

r, w = os.pipe()
pid = os.fork()

if pid:
    try:
        os.close(r)

        b = b''
        while True:
            ins, _, _ = select.select([sys.stdin], [], [], 1)
            if ins:
                d = os.read(0, 1)
                print('parent read', d)
                if d == b'\n':
                    break
                b += d
        print('parent writing', b)
        os.write(w, b)
    finally:
        os.close(w)
else:
    os.close(w)
    sys.stdin.close()
    sys.stdin = os.fdopen(r)
    print('asking for input')
    d = raw_input('Enter your input: ')
    print(d)
    sys.exit(0)
以及输出:

python2 p2.py
asking for input
a
('parent read', 'a')
('parent read', '\n')
('parent writing', 'a')
Enter your input: a
而在python3(将原始输入更改为输入)下,它可以按预期工作:

python3 test.py
asking for input
Enter your input: a
parent read b'a'
parent read b'\n'
parent writing b'a'
a

可以通过执行
os.fdopen(r,'r',1)
或运行
PYTHONUNBUFFERED=1 python2 p2.py
python2-u p2.py
来修复。我认为第一种方法是最好的,因为它不会影响stdout和其他进程。python 2的fdopen是一个cpython posix实现,而在python 3中,fdopen是io.open的包装器。在Python2中使用io.open时,无论我设置的缓冲区大小如何,我都会遇到同样的问题(尽管上面提到的其他两种方法仍然有效)。