2014-10-09 9 views
0

백그라운드 스레드에서 PyZMQ 이벤트 루프를 만들고 독립 실행 형 Python 스크립트와 IPython 스크립트 모두에서 제대로 작동하도록하고 싶습니다. (IPython은 메인 스레드에있는 PyZMQ 이벤트 루프를 사용하므로 문제가 발생하고 배경 스레드에서 개인 ioloop을 시작해야하는 이유가 무엇입니까?)두 번째 zmq.eventloop.ioloop을 실행합니다.

PyZMQ 이벤트 루프 핸들을 사용하면서 스레드 A에서 코드를 실행하고 싶습니다. 스레드 B의 소켓에서받은 데이터입니다. 스레드 A에서 스레드 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 

를 + 입력 내가 WRO 일을 할 수있는 무엇 메인 스레드에서 IOLoop 개체입니다,하지만 내 개인적인 예를 IOLoop는 결코 하이 인쇄합니다

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

.

응?

답변

0

아아, 나는 단지 토네이도 문서에서 이것을 발견 : 다른 스레드에서 add_timeout를 호출하는 것은 안전하지 않습니다

하는 것으로. 대신 add_callback을 사용하여 IOLoop의 스레드로 제어를 전송 한 다음 add_timeout을 호출해야합니다.

제대로 작동하려면 ioloop과 동일한 스레드에서 zmq.eventloop.zmqstream을 설정해야하는 것처럼 보입니다.