Push-сокет ZeroMQ приводит к тому, что клиент не завершает работу, когда ни один процесс не прослушивает - PullRequest
4 голосов
/ 28 января 2012

Я только начинаю связываться с ZeroMQ, и у меня проблема с клиентом, который обычно не завершается.В частности, у меня есть клиент, который может «выдвигать» данные, когда никакой сервер-приемник не слушает, и это, кажется, заставляет процесс зависать после завершения кода Python.Я предполагаю, что есть некоторый фоновый поток, который необходимо очистить - пожалуйста, скажите мне, как или укажите на документацию.

Вот соответствующий фрагмент кода.Если я запускаю процесс без прослушивателя с незакомментированной строкой self.push, процесс зависает

def setup(self):
    print self.name, "connect to sockets"
    ctx = self.ctx = zmq.Context()
    self.pull = ctx.socket(zmq.PULL)
    self.pull.connect(self.ventillatorAddress)
    self.push = ctx.socket(zmq.PUSH)
    self.push.connect(self.sinkAddress)
    self.control = ctx.socket(zmq.SUB)
    self.control.connect(self.publisherAddress)
    self.control.setsockopt(zmq.SUBSCRIBE, "") # get every control message
    self.inbox = ctx.socket(zmq.SUB)
    self.inbox.connect(self.distributorAddress)
    self.inbox.setsockopt(zmq.SUBSCRIBE, self.name) # listen only for messages addressed with name
def start(self):
    print self.name,  "push worker is ready signal"
    # listen for "go" signal
    pollcount = 0
    go = False
    while not go:
        #print "send ready for", self.name
        #self.push.send(self.name+" ready")
        print "listen for 'go'"
        msg = self.recvPoll(self.control)
        if msg is None:
            pollcount += 1
            assert pollcount<10
            print "poll timeout", pollcount
            time.sleep(1)
            continue
        pollcount = 0
        print "recv'd", msg
        assert msg=="go!"
        go = True
    print "go signal received"
    pass

С закомментированной строкой (без прослушивателя) процесс завершается нормально.Я попытался context.term () и context.destroy (), и они, кажется, не помогают.

Как я могу очистить сокет?Или какие-то другие подсказки?Заранее спасибо!

1 Ответ

4 голосов
/ 28 января 2012

Это, скорее всего, связано с функциональностью linger в ZeroMQ. Цитата из справочной страницы :

Опция ZMQ_LINGER должна устанавливать период задержки для указанного сокета. Период задержки определяет, как долго ожидающие сообщения, которые еще должны быть отправлены одноранговому узлу, должны задерживаться в памяти после закрытия сокета с помощью zmq_close (3), и дополнительно влияет на завершение контекста сокета с помощью zmq_term (3).

Значение по умолчанию заставляет ZeroMQ ждать неопределенно долго, пока он не сможет доставить застрявшее сообщение.

Попробуйте установить для параметра сокета ZMQ_LINGER значение ноль или короткое время (в миллисекундах).

...