2017-12-12 10 views
1

이것은 프로젝트에서 asyncio을 사용하기위한 첫 번째 시도입니다. 내 클래스를 초기화하고 실행하고, 여러 함수가 백그라운드에서 주기적으로 실행되도록하고 싶습니다. 클래스의 init가 이러한 백그라운드 작업을 시작한 후에 돌아와서 동시에 동기 작업을 계속할 수 있기를 바랍니다.asyncio가있는 백그라운드에서 스레드 클래스의 함수 실행

내가 무엇을 가지고 :

class MyClass(threading.Thread): 
    def __init__(self, param): 
     self.stoprequest = threading.Event() 
     threading.Thread.__init__(self) 

     self.param = param 

     self.loop = asyncio.new_event_loop() 
     asyncio.set_event_loop(self.loop) 
     asyncio.ensure_future(self.periodic(), loop=self.loop) 

     print("Initialized") 

    async def periodic(self): 
     while True: 
      print("I'm here") 
      await asyncio.sleep(1) 

    def run(self): 
     # continue to do synchronous things 

나는 당연히 확신이 작동하지 않습니다. 나는 또한 "normal"asyncio 함수를 사용하여 run_until_complete()을 init에서 시도했지만, 물론 init은 결코 반환하지 않습니다.

나머지 클래스 (run())가 동기 작업을 계속하는 동안이 클래스에 속하는 asyncio 함수를 백그라운드에서 주기적으로 실행할 수 있습니까?

답변

2

루프를 인수로 사용하여 ensure_future에 전달하면이 루프가 시작되지 않습니다. 코 루틴을 강제로 시작하려면 run_until_complete 또는 run_forever으로 전화해야합니다. 다른 방법은 없습니다.

어떻게 클래스의 나머지 (실행은()) 동기 작업을 계속하는 동안,이 클래스 백그라운드에서 주기적으로 에 속하는 asyncio 기능을 실행할 수 있습니까?

수 없습니다. 주 스레드에서 이벤트 루프와 동시 코드를 동시에 실행할 수 없기 때문입니다. Loop starting - 루프가 중지 될 때까지 스레드의 실행 흐름을 차단합니다. 이것은 asyncio의 작동 방식입니다.

백그라운드에서 asyncio을 실행하려면 별도의 스레드에서 실행하고 동기 스레드를 주 스레드에서 실행해야합니다. 그것을하는 방법의보기는 here 찾을 수 있습니다.

그것은 당신이 메인 스레드에서 asyncio를 실행하고 run_in_executor 기능을 사용하여 백그라운드 스레드에서 코드를 차단 실행하는 것입니다 지금 함께 asyncio 가장 편리한 방법으로 스레드에서 코드를 차단 실행해야합니다. 그것을 수행하는 예제는 here입니다.

비동기 프로그래밍의 이점을 얻으려면 asyncio 자체가 다른 스레드가없는 주 스레드에서 주로 사용되는 것이 중요합니다. 두 번째 스레드가 필요합니까? 그렇지 않다면 this answer을 읽고 asyncio이 사용 된 이유를 확인하십시오.