2016-07-13 7 views
1

Существует ли наилучший подход к опросу для stdout/stderr от subprocess.Popen, а также к сокету zmq?Перемещение stdout из Popen с сообщениями из ZMQ recv

В моем случае у меня есть моя основная программа, создающая подпроцесс Popen. Подпроцесс публикует сообщения через zmq, которые затем я хочу подписаться в моей основной программе.

Ожидание нескольких сокетов zmq не осложняется с помощью zmq.Poller, но когда я хочу чередовать это с выходом самого моего подпроцесса, я не уверен, как это сделать наилучшим образом, не рискуя ожиданиями или ненужными циклами.

В конце концов, я хотел бы использовать его так:

process = Popen([prog, '--publish-to', 'tcp://127.0.0.1:89890'], 
     stdout=subprocess.PIPE, stderr=subprocess.PIPE, ...) 
for (origin, data) in interleave(process, 'tcp://127.0.0.1:89890'): 
    if origin == 'STDOUT': pass 
    if origin == 'STDERR': pass 
    if origin == 'ZMQ': pass 

prog --publish-to tcp://127.0.0.1:89890 затем откроет zmq.PUB сокет и публикации данных, в то время как функция перемежать будет подписаться на это, а также опрашивать стандартный вывод и стандартный поток ошибок , yield.

Я знаю, как определить interleave с несколькими потоками и очередями демона, но я не знаю, может ли этот подход иметь некоторые оговорки относительно ленивого чтения (то есть, stdout может не обрабатываться до конца программы?) или другие вещи, о которых я еще не думал (по-видимому, это тоже немало накладных расходов для такой задачи).

Я буду благодарен за все идеи или идеи.

Я нацелен хотя бы на Python 3.3/3.4, но если это будет намного проще с новыми инструментами async/await, я бы тоже использовал Python 3.5 для кода.

+0

Вы можете получить дескриптор целочисленного файла, используя 'process.stdout.fileno()'. Если вы можете получить файловый дескриптор сокета zmq, вы можете выполнить вызов 'select.select ((fd1, d2, fd3),(),(), None)', чтобы дождаться первого. Если нет способа получить файловый дескриптор сокета zmq, вы можете создать 2 или 3 потока, оба из которых считывают (и блокируются) из одного источника, помещая данные чтения в 'Queue'. – pts

+0

Хм, будет 'выбирать' работу над окнами? К сожалению, это будет пробкой. – Debilski

+0

См. Также: http://stackoverflow.com/questions/9448247/zeromq-zmq-poller-stdin – Debilski

ответ

1

zmq.Poller: http://pyzmq.readthedocs.io/en/latest/api/zmq.html#polling. Вы можете зарегистрировать сокеты zmq и собственные файловые дескрипторы (например, process.stdout.fileno() и process.stderr.fileno()), и он будет ожидать, пока вход будет доступен, по крайней мере, из одного из зарегистрированных источников.

Я не знаю, работает ли он в Windows, вы должны попробовать.

+0

Нельзя работать с Windows, к сожалению, но я нашел обходное решение как минимум. Благодарю. http://stackoverflow.com/a/20807648/200266 – Debilski

 Смежные вопросы

  • Нет связанных вопросов^_^