Этот вопрос был также опубликован как выпуск pyzmq на GitHub. Я перефразирую свое объяснение здесь (я надеюсь, что это уместно, я довольно новичок в SO):
Общее правило: если есть сомнения, зависания в конце вашей программы zeromq происходят из-за LINGER.
Зависание здесь вызвано опцией сокета LINGER и происходит в методе context.term()
, вызываемом во время сборки мусора в самом конце скрипта. Поведение LINGER описано в документации zeromq, но, проще говоря, это время ожидания (в миллисекундах) для ожидания любых ожидающих сообщений в очереди после закрытия сокета, прежде чем отбрасывать сообщения , Поведение по умолчанию - LINGER=-1
, что означает ожидание вечно.
В этом случае, поскольку ни один узел не был запущен, сообщение «привет», которое вы пытались отправить, все еще ожидает в очереди отправки, когда сокет пытается закрыться. При LINGER=-1
ZeroMQ будет ждать, пока узел не будет готов принять это сообщение, прежде чем завершить работу. Если вы связываете сокет REP с 'ipc: ///tmp/idontexist.socket', когда этот скрипт, по-видимому, зависает, сообщение будет доставлено, и скрипт завершит корректный выход.
Если вы не хотите, чтобы ваш скрипт ждал (как указано в ваших инструкциях печати, которые вы уже отказались от получения ответа), задайте для LINGER любое неотрицательное значение (например, socket.linger = 0
) и context.term()
вернется после ожидания указанного количества миллисекунд.
Следует отметить, что имя переменной INVALID_ADDR предполагает понимание того, что подключение к интерфейсу, у которого еще нет прослушивателя, недопустимо - это неверно. zeromq позволяет событиям bind / connect происходить в любом порядке, как показано вышеописанным поведением привязки сокета REP к интерфейсу, в то время как скрипт отправки блокирует term()
.