Вывод:
Kancler@Kanc1er-pc ~
$ python myprogs/pipes.py
Child 1849 of 1848 got arg: "spam"
Traceback (most recent call last):
File "myprogs/pipes.py", line 31, in <module>
reply = input()
File "<string>", line 1
Child 1849 got: ('Hello 1 from parent ', 1848)
^
SyntaxError: invalid syntax
Kancler@Kanc1er-pc ~
$ Traceback (most recent call last):
File "myprogs/pipe-testchild.py", line 10, in <module>
recv = input()
EOFError: EOF when reading a line
Родительская программа (pipe.py):
import os, sys def spawn(prog, *args): # имя программы, аргументы командной строки stdinFd = sys.stdin.fileno() # получить дескрипторы потоков stdoutFd = sys.stdout.fileno() parentIn, childOut = os.pipe() # создать два канала IPC childIn, parentOut = os.pipe() # pipe возвращает (inputfd, outoutfd) pid = os.fork() # создать копию процесса if pid: os.close(childOut) # в родительском после ветвления: os.close(childIn) # закрыть дочерние концы в родителе os.dup2(parentIn, stdinFd) # копия sys.stdin = pipe1[0] os.dup2(parentOut, stdoutFd) # копия sys.stdout = pipe2[1] else: os.close(parentIn) # в дочернем после ветвления: os.close(parentOut) # закрыть родительские концы os.dup2(childIn, stdinFd) # копия sys.stdin = pipe2[0] os.dup2(childOut, stdoutFd) # копия sys.stdout = pipe1[1] args = (prog,) + args os.execvp(prog, args) # запустить новую программу assert False, 'execvp failed!' if __name__ == '__main__': mypid = os.getpid() spawn('python', 'myprogs/pipe-testchild.py', 'spam') # породить дочернюю прогр. print('Hello 1 from parent ', mypid) # в stdin дочерней прогр. sys.stdout.flush() # вытолкнуть буфер stdio reply = input() # из потока вывода потомка sys.stderr.write('Parent got: "%s"\n' % reply) # stderr не связан с каналом print('Hello 2 from parent ', mypid) sys.stdout.flush() reply = input() sys.stderr.write('Parent got: "%s"\n' % reply[-1])
Дочерняя программа(pipe-testchild.py):
import os, sys, time mypid = os.getpid() parentpid = os.getppid() sys.stderr.write('Child %d of %d got arg: "%s"\n' % (mypid, parentpid, sys.argv[1])) for i in range(2): time.sleep(2) # приостановить родительский процесс recv = input() # stdin связан с каналом: данные будут поступать из time.sleep(2) # родительского потока вывода stdout send = 'Child %d got: %s' % (mypid, recv) print(send) # stdout связан с каналом: данные будут поступать в # родительский поток ввода stdin sys.stdout.flush() # гарантировать отправку, иначе процесс заблокируется