Нужен обходной путь: Python select.select () не работает с stdout подпроцесса? - PullRequest
1 голос
/ 08 октября 2009

Из моей основной программы Python я создаю дочернюю программу с этим кодом:

child = subprocess.Popen(..., stdout=subprocess.PIPE, stdin=subprocess.PIPE)

FWIW, дочерний элемент - это PHP-скрипт, который должен обмениваться данными с программой на python.

Мастер-программе Python на самом деле нужно прослушивать связь из нескольких других каналов - другие PHP-скрипты, порожденные с использованием того же кода, или объекты сокетов, полученные из socket.accept(), и я хотел бы использовать select.select(), так как это наиболее эффективный способ ожидания ввода от различных источников.

Проблема, с которой я столкнулся, заключается в том, что select.select() под Windows не работает с дескриптором файла stdout подпроцесса (это задокументировано), и, похоже, я буду вынужден:

  • A) Опрос PHP-скриптов, чтобы увидеть, написали ли они что-нибудь для stdout. (Эта система должна быть очень отзывчивой, мне нужно опрашивать не менее 1000 раз в секунду!)
  • B) Подключите сценарии PHP к главному процессу и обменивайтесь данными через сокеты вместо stdout / stdin.

Я, вероятно, пойду с решением (B), потому что я не могу заставить себя проводить системный опрос с такой высокой частотой, но кажется грустной тратой ресурсов на повторное соединение с сокетами, когда stdout / stdin сделал бы просто отлично.

Есть ли альтернативное решение, которое позволило бы мне использовать стандартный вывод и select.select()?

1 Ответ

4 голосов
/ 08 октября 2009

К сожалению, многие способы использования каналов в Windows работают не так хорошо, как в Unix, и это одно из них. В Windows лучшее решение, вероятно, состоит в том, чтобы ваша основная программа порождала потоки для прослушивания каждого из ее подпроцессов. Если вам известна гранулярность данных, которые вы ожидаете от своего подпроцесса, вы можете заблокировать чтение в каждом из ваших потоков, и тогда поток оживет, когда IO разблокируется.

В качестве альтернативы (я понятия не имею, подходит ли это для вашего проекта), вы могли бы изучить использование Unix-подобной системы или Unix-подобного слоя поверх Windows (например, Cygwin), где select.select() будет работа на подпроцессных трубах.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...