2013-12-15 2 views
1

Я пытаюсь воспроизвести парадигму вентилятора/рабочих/раковины, описанную в руководстве ZMQ. У меня такой же Python Ventilator, тот же рабочий C++, как и тот же Python Sink, как описано в примерах ZMQ. Я хочу запустить вентилятор, рабочих и потопить из одного основного скрипта python, поэтому я создал «классные» обертки вокруг вентилятора &, и оба эти класса подкласса модуля «многопроцессорность» Python. Поскольку C++ является двоичным, я запускаю его с помощью подпроцесса Python.Popen.zmq вентилятор/рабочая/раковина парадигма не работает с подпроцессом

Порядок запуска все это вверх следующим образом:

h = subprocess.Popen('test') # test is the name of the binary 
time.sleep(1) 
s = sinkObj.start() 
time.sleep(1) 
v = ventObj.start() 

То, что я нахожу, что никакие данные не получает через систему, когда я запустить компоненты, как это. Однако, если я запустил двоичный код C++ в своей собственной оболочке и только запустил sinkObj и ventObj из основного скрипта python, он отлично работает.

Я заранее извиняюсь, если это вопрос Python скорее, чем вопрос ZMQ, но я не сталкивался с такими проблемами, как этот подпроцесс w/Python. Я также пробовал использовать os.system() вместо подпроцесса ... но такую ​​же проблему. Я размещаю весь код на этом сайте: https://github.com/kkarrancsu/zmqtest, если кому-то интересно проверить его. В этом git есть readme, который сообщает вам, что такое файлы.

Любые идеи о том, почему это может произойти?

------------------------- ОБНОВЛЕНИЕ --------------------

Я обнаружил, что если я создаю скрипт оболочки, который просто запускает двоичный файл C и вызывает этот сценарий оболочки w/os.system ('run_the_shell_script'), он работает! Таким образом, это означает, что что-то не так с тем, как я использую subprocess.Popen (...), но не могу точно определить, в чем проблема. Я попробовал w/shell = True flag, но он все еще висит с этим ...

ответ

0

Как я вижу, вентилятор и раковина bind() к портам 6557 и 6558 и приложение C++ connect() к этим портам. В этом случае, если вы сначала запустите приложение cpp, оно будет пытаться до connect() к конечным точкам, но поскольку там ничего не привязано, оно будет тихо исчезать. В ZeroMQ основным принципом является «First Bind, затем Connect». Поэтому вы не должны connect() перед вами bind() что-то на сокете. Представьте себе, что bind() является «сервером», а connect() является клиентом. Вы не можете подключить клиента к несуществующему серверу. Кроме того, в ZeroMQ каждый сокет может быть «Сервером», но вы ДОЛЖНЫ ИМЕТЬ только 1 bind() - сокет на каждый URL. И вы можете иметь несколько «connect()».

+0

Я попробовал ваше предложение, переместив код подпроцесса.Popen (который запускает двоичный код C++, который вызывает 'connect()' ПОСЛЕ запуска и вентилятора и приемника (который связывается), но все та же проблема. через, когда я запускаю двоичный код C++ из python с помощью 'subprocess.Popen' –

1

Это имя двоичного файла worker, вызывающего проблему.

Там два решения:

  • Чанг имя двоичного файла тест к test_new и сделать то же самое в вашем All.py файл, а затем она будет работать, как вы хотите.
  • Замещение subprocess.Popen('./test', shell=True) для subprocess.Popen('test', shell=True).

test - это команда Linux.Если вы введите в вашей оболочке

$ echo $PATH 

Вы можете видеть, что . находится на последнем месте. Это означает, что до тех пор, пока оболочка не сможет найти бинарный файл, который будет выполняться в каталогах, которые указывают $ PATH, он попытается найти его в текущем каталоге. .
Когда вы выполните subprocess.Popen('test', shell=True), он может найти его перед попыткой . и поэтому он не будет выполнять workers.