2017-10-30 12 views
2

글쎄 파이썬에서 비동기를 처음 사용했습니다. asyncio.start_server 호출을 사용하여 서버를 만들고 있는데 문제는 동일한 루프를 두 번 실행하고 처음으로 서버를 작성/시작하는 것입니다. loop.run_until_complete을 호출하고 그 후에 loop.run_forever을 호출합니다. 여기 내가 사용하는 코드.파이썬 asyncio 이벤트 루프. 비동기 작업을 완료 한 후 영원히 루프를 실행하십시오.

if __name__ == '__main__': 
    loop = asyncio.get_event_loop() 

    sv_wrapper = ServerWrapper(
     host='localhost', 
     port=5003 
    ) 

    loop.run_until_complete(sv_wrapper.create()) 
    print(repr(sv_wrapper.server)) 

    loop.run_forever() 

(Full code example)
솔직히 내가 loop.run_forever() 마지막 호출을 얻을하지 않습니다 는 호출을 실행 같은 이벤트 루프, 또는 새로운 이벤트 루프에 asyncio.start_server 실행에 드 작성된 서버는 내부적으로 생성 하는가?

새로운 이벤트 루프가 내부적으로 생성 된 경우, 프로세스 실행을 유지하는 것만으로도 충분할 수 있습니다 (물론 생성 된 Server에 대한 참조가 있음).

전혀 이해할 수 있는지 모르겠지만 서버 자체가 루프 (향후 작업으로 들어오고 나가는 연결을 관리) 인 경우 loop.create_task으로 작업을 푸시 할 수 있습니까?

나는 특정 문제가 발생하지 않았으며 그것에 대해 유감스럽게 생각합니다. 나는 nodejs 배경에서 왔고, 파이썬에서 비동기를 얻는 것이 더 쉬울 거라고 생각했다. 도움을 주셔서 감사하며, 어떤 엑스트라도 잘받을 것이다!

답변

1

솔직히 내가) (loop.run_forever하는 마지막 호출을하지 않는, 내부적으로 생성 된 전화, 또는 새로운 이벤트 루프를 실행 같은 이벤트 루프 에 asyncio.start_server 실행에 작성된 서버를 해제 않습니다 ?

단일 전역 이벤트 루프입니다. 일반적으로 최종 사용자는 이벤트 루프를 만들고 실행하며 라이브러리는 내부적으로 이벤트 루프를 수행하지 않습니다. 새로운 이벤트 루프가 내부적으로 생성되는 경우

, 나는 충분히 (물론 생성 된 서버에 대한 참조를 갖는)이 될 수있는 실행중인 프로세스를 유지 예를 들어, 영원히 실행에 대한 호출이 필요하지 않습니다. 잘 모르겠어요

난 당신이 무슨 뜻인지 이해하지만, 여기에 몇 가지 생각 :

  1. 서버가 이벤트 루프가 실행되는 동안에 만 사용할 수 있습니다. 서버는 이벤트 루프를 통해서만 무언가를 받거나 보낼 수 있습니다.

  2. loop.run_until_complete(sv_wrapper.create())은 이벤트 이 하나의 작업 (서버 작성)을 실행하고 중지되는 데 사용되는 루프를 의미합니다. 다시 말해 작성된 서버 작업을 수행하기 위해이를 실행해야 함을 의미합니다.

나는 그것을 루프와 함께 작업을 추진하는 것이 가능이 모든 감각을 가지고 있는지 알고 있지만, 서버가 루프 자체 인 경우 (향후 과제로/나오는 연결에서 관리)하지 않습니다. create_task?

서버 자체가 이벤트 루프가 아닙니다. 대략 말하자면, 서버는 글로벌 이벤트 루프에 의해 관리되는 비동기 작업 중 하나입니다.

동일한 전역 이벤트 루프 (및 서버와 동시에 실행되는 것을 통해 관리 됨)에서 관리되는 다른 비동기 작업 (과 함께 수행하려면 better)을 만들 수 있습니다.

0

왜 소스 코드를 확인하지 않으시겠습니까?

try: 
    events._set_running_loop(self) 
    while True:     # Here is the point. 
     self._run_once()   # Run event loop once. 
     if self._stopping:  # Check stop 
      break     # Stop event loop. 
finally: 
    self._stopping = False 
    self._thread_id = None 
    events._set_running_loop(None) 
    self._set_coroutine_wrapper(False) 
    if self._asyncgens is not None: 
     sys.set_asyncgen_hooks(*old_agen_hooks) 

이 부분은 run_forever의 일부입니다. 전화 run_forever 없이는 아무 작업도 수행하지 않습니다.