2014-10-09 2 views
0

Я хочу создать eventloop PyZMQ в фоновом потоке и работать корректно с помощью автономных скриптов Python и скриптов IPython. (IPython использует PyZMQ eventloops, расположенный в основном потоке, так что это вызывает у меня проблемы и почему я хочу запустить частный ioloop в фоновом потоке.)работает со вторым zmq.eventloop.ioloop

Я хочу запустить код в Thread A, имея дескриптор события PyZMQ полученные данные из сокета в потоке B. В Thread A есть моменты, когда мне нужно будет дождаться события, установленного в Thread B.

Как я могу заставить это работать? Там, кажется, что-то не так, если я пытаюсь в IPython:

from zmq.eventloop import ioloop 
import threading 

class IOBackgroundLoop(object): 
    def __init__(self): 
     self._loop = None 
     self._thread = threading.Thread(target=self.run)   
     self._thread.daemon = True 
     self._started = threading.Event() 
    @property 
    def loop(self): 
     return self._loop 
    def run(self): 
     self._loop = ioloop.IOLoop() 
     self._loop.initialize() 
     self._loop.make_current() 
     self._started.set() 
     self._loop.start() 
    def start(self): 
     self._thread.start() 
     self._started.wait() 

bkloop = IOBackgroundLoop() 
bkloop.start() 
for loop in [bkloop.loop, ioloop.IOLoop.instance()]: 
    print "%s running: %s" % (loop, loop._running) 

Это печатает две отдельные экземпляры IOLoop, но если я иду, чтобы использовать его, это не похоже на работу. Я не могу придумать небольшую примерную программу, чтобы продемонстрировать это; Я попытался с помощью функции тайм-аут:

import time 

def print_timestamp(key): 
    print "%s: %s" % (time.time(), key) 

for loop in [bkloop.loop, ioloop.IOLoop.instance()]: 
    loop.add_timeout(bkloop.loop.time() + 1.0, lambda: print_timestamp("hi from %s" % loop)) 
    print_timestamp("here") 
    time.sleep(2.0) 
    print_timestamp("there") 

и я получаю это в результате (без "привет":

1412889057.68: here 
1412889059.68: there 
1412889059.68: here 
1412889061.68: there 

Затем, когда я ударил другого Shift + Enter, я получаю

1412889061.68: hi from <zmq.eventloop.ioloop.ZMQIOLoop object at 0x000000000467E4E0> 

который является объектом IOLoop от основного потока, но мой частный случай IOLoop никогда не печатает привет.

Что я мог бы делать WRO нг?

ответ

0

Argh, я только что заметил это в торнадо документы:

Обратите внимание, что это не безопасно вызывать add_timeout из других потоков. Вместо этого вы должны использовать add_callback для управления передачей в потоке IOLoop, а затем позвонить add_timeout.

Похоже, что необходимо установить zmq.eventloop.zmqstream в той же теме, что и ioloop, чтобы она работала правильно.