为什么我不能在这个分叉的进程中读取stdin?

时间:2012-09-06 20:51:11

标签: python fork stdin pty

以下代码不打印任何内容,但应该打印出来" a"反复。分叉的进程在os.read(0,1)上阻塞。父进程确实正在写入stdin_master,但是stdin_slave什么都没有收到。有什么想法吗?

import os
import pty
import resource
import select
import signal
import time


stdin_master, stdin_slave = pty.openpty()
stdout_master, stdout_slave = pty.openpty()
stderr_master, stderr_slave = pty.openpty()

pid = os.fork()

# child process
if pid == 0:
    os.setsid()
    os.close(stdin_master)
    os.close(stdout_master)
    os.close(stderr_master)

    os.dup2(stdin_slave, 0)
    os.dup2(stdout_slave, 1)
    os.dup2(stderr_slave, 2)

    max_fd = resource.getrlimit(resource.RLIMIT_NOFILE)[0]
    os.closerange(3, max_fd)


    while True:
        char = os.read(0, 1)
        os.write(1, char)

    os._exit(255)

# parent process
else:
    os.close(stdin_slave)
    os.close(stdout_slave)
    os.close(stderr_slave)

    try:
        while True:
            read, write, err = select.select([stdout_master], [stdin_master], [], 0)
            for to_read in read:
                print os.read(to_read, 1)

            for to_write in write:
                os.write(to_write, "a")

            time.sleep(0.1)

    finally:
        os.kill(pid, signal.SIGKILL)

2 个答案:

答案 0 :(得分:1)

我不确定您是否希望在此处使用pty模块。你似乎需要的基本上是一对os.pipe

这是一个使用管道的解决方案:

import os
import select
import signal
import time


stdin_slave, stdout_master = os.pipe()
stdin_master,stdout_slave  = os.pipe()

pid = os.fork()

# child process
if pid == 0:

    while True:
        char = os.read(stdin_slave, 1)
        os.write(stdout_slave, char)

    os._exit(255)

# parent process
else:
    try:
        while True:
            read, write, err = select.select([stdin_master], [stdout_master], [], 0)

            for to_read in read:
                print os.read(to_read, 1)

            for to_write in write:
                os.write(to_write, "a")

            time.sleep(0.1)

    finally:
        os.kill(pid, signal.SIGKILL)

答案 1 :(得分:1)

Thomas Wouters非常友好地提供了答案:

只能从主fd读取PTY。因此,孩子的os.read(0,1)因此没有工作。如果我们改变

stdin_master, stdin_slave = pty.openpty()

stdin_slave, stdin_master = pty.openpty()

现在chlid将从主人那里读取,我们将从父母那里写入奴隶。这很有效。