Мне нужно запустить подпроцесс и включить два потока для чтения его stdout
и stderr
соответственно.Промывка трубы (os.pipe) перед закрытием
Следующий код только с учетом stdout
:
def reader(rfd):
while True:
try:
data = os.read(rfd, bufsize)
except OSError:
break
else:
chomp(data)
rout, wout = os.pipe()
tout = threading.Thread(target=reader, args=(rout,))
tout.start()
subprocess.check_call(command, bufsize=bufsize, stdout=wout, stderr=werr)
os.close(wout)
os.close(rout)
tout.join()
код работает, за исключением того, я заметил, что не все данные обрабатываются, как если бы функция os.close(wout)
убивает читатель до того считываются все данные. С другой стороны, если я не закрываю wout
, мой процесс будет вешать навсегда на tout.join()
.
Я могу сказать, что это проблема буферизации, потому что, если я положил очень плохо time.sleep(0.1)
сразу после subprocess.check_call(...)
все волшебным образом работает.
Хорошим способом будет промывка, а не ожидание, но любой вызов os.fsync()
по трубе дает OSError: [Errno 22] Invalid argument
.
Любой намек на то, как очистить трубу, созданную с помощью os.pipe
?
Почему вы закрываете трубы * до * присоединения нити? – goncalopp
@goncalopp, 'close' прерывает' read'. Если вы делаете обратное, вы получаете тупик, так как нить никогда не заканчивается. – Dacav
Вы пытались использовать 'subprocess.Popen' с' stdout = subprocess.PIPE'? Кроме того, вы уверены, что это не вызов для закрытия «маршрута», который является проблемой? – Dunes