Пример для вас, где вы читаете и пишете ребенку несколько раз (как вы указали в комментарии под вопросом).
Подпроцесс (test.py
) будет:
- прочитать строку
- преобразовать каждую строку в верхний регистр и записать ее обратно,
- спать 2 секунды
- повторять до тех пор, пока не закончится ввод, а затем напишите окончательный строка
Основной процесс (main.py
) будет:
- три раза:
- записать строку ввода в подпроцесс
- прочтите ответ и скажите, сколько времени потребовалось, чтобы получить ответ
- сон 5 секунд
- в конце, прочтите любой окончательный результат, используя
communicate
, и сообщите об этом
Вот результат кода, который показан ниже:
writing to child: hello world 0
child replied with: HELLO WORLD 0
got answer back within 0.00022 seconds
writing to child: hello world 1
child replied with: HELLO WORLD 1
got answer back within 0.00012 seconds
writing to child: hello world 2
child replied with: HELLO WORLD 2
got answer back within 0.00021 seconds
final output from child: finishing
А вот код:
test.py
import sys
import time
while True:
value = sys.stdin.readline()
if not value:
break
sys.stdout.write(value.upper())
sys.stdout.flush()
time.sleep(2)
sys.stdout.write("finishing\n")
main.py
from subprocess import Popen, PIPE, STDOUT
import time
child = Popen(['python.exe', 'test.py'], stdin=PIPE, stdout=PIPE, stderr=STDOUT)
time.sleep(1)
for i in range(3):
data_in = f"hello world {i}"
print(f"writing to child: {data_in}")
time0 = time.time()
child.stdin.write(f"{data_in}\n".encode())
child.stdin.flush()
data_out = child.stdout.readline()
time1 = time.time()
result = data_out.decode().strip()
elapsed_time = time1 - time0
print(f"child replied with: {result}")
print(f"got answer back within {elapsed_time:.5f} seconds\n")
time.sleep(5)
output, error = child.communicate()
print(f"final output from child: {output.decode()}")
(Проверено на Linux с использованием python
вместо python.exe
- надеюсь, он будет одинаково работать на Windows, хотя я могу Не тестирую.) * 105 1 *
Как видите, ответ получен, не дожидаясь завершения sleep
.
(Очевидно, если время сна в родительском элементе уменьшится до менее 2 секунд, тогда ребенок не будет готов получить данные, когда они будут отправлены, так что тогда придется больше ждать, чтобы получить ответ.)
С таким двусторонним общением это очень просто оказаться в тупиковой ситуации (каждый процесс ждет, пока другой что-то сделает). Чтобы избежать этого, каждый процесс записывает ровно одну строку каждый раз, гарантируя, что она заканчивается новой строкой, и немедленно очищает выходной буфер - а процесс чтения использует readline()
для чтения ровно одной строки (читается до новой строки). Тогда, надеюсь, они будут идти в ногу со временем и избежать взаимоблокировок.