Я пытаюсь воспроизвести парадигму вентилятора / рабочих / раковин, описанную в руководстве ZMQ. У меня есть тот же Python Ventilator, тот же рабочий C ++ и тот же Python Sink, который был описан в примерах ZMQ. Я хочу запустить вентилятор, рабочих и приемник из одного основного скрипта Python, поэтому я создал «классные» обертки вокруг вентилятора & раковина, и оба этих класса подкласс Python-модуля «multiprocessing.Process.» Поскольку C ++ является двоичным файлом, я запускаю его с помощью вызова подпроцесса Python.
Порядок запуска всего этого следующий:
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, но я не сталкивался с такими проблемами, как этот подпроцесс с Python. Я также попытался использовать os.system () вместо подпроцесса … но та же проблема. Я разместил весь код на этом сайте: https://github.com/kkarrancsu/zmqtest если кому-то интересно проверить это. На этом git есть readme, который сообщает вам, что это за файлы.
Любые идеи о том, почему это может происходить?
————————- ОБНОВИТЬ ———————
Я обнаружил, что если я создаю сценарий оболочки, который просто запускает двоичный файл C, и вызываю этот сценарий оболочки без os.system (‘run_the_shell_script’), это работает! Таким образом, это означает, что что-то не так с тем, как я использую subprocess.Popen (…), но не могу точно определить, в чем проблема. Я попробовал w / shell = True flag, но он все еще зависает …
Это имя worker
двоичный файл, который вызывает проблему.
Там два решения:
subprocess.Popen('./test', shell=True)
за subprocess.Popen('test', shell=True)
,test
это команда Linux Если вы введете следующее в вашей оболочке
$ echo $PATH
Вы можете видеть, что .
находится на последней позиции. Это означает, что до тех пор, пока shell не сможет найти исполняемый двоичный файл в каталогах, указанных в $ PATH, он будет пытаться найти его в текущем каталоге .
Когда вы выполняете subprocess.Popen('test', shell=True)
, он может найти его, прежде чем пытаться .
каталог и поэтому он не будет выполнять workers
,
Как я вижу, вентилятор и мойка bind()
на порты 6557 и 6558 и приложение C ++ connect()
в эти порты. В этом случае, если вы начнете cpp
приложение сначала попытается connect()
до конечных точек, но так как ничто не связано там, оно будет тихо падать.
В ZeroMQ основной принцип — «Сначала связывай, потом соединяйся». Так что не стоит connect()
до тебя bind()
что-то на сокете. Представить bind()
это «Сервер», и connect()
это клиент. Вы не можете подключить клиента к несуществующему серверу. Кроме того, в ZeroMQ каждый сокет может быть «Сервером», но вы ДОЛЖНЫ ИМЕТЬ только 1 сокет bind () на URL. И вы можете иметь несколько ‘connect ()’.