비동기 파이썬 코 루틴 흐름 분석 공정 (a)

더 나은 프리젠 테이션을 위해, 나는 세 가지 기능, 동기화 기능이 개 비동기 기능을 준비

#DEFINE 기능을 차단 
: DEF 핑 (URL) 
    ( "차단 기능이 실행을 시작") 인쇄를 
    time.sleep (2) 
    os.system을 ( "핑 %의 S"%의 URL) 
    인쇄 ( "실행의 끝 차단 기능") 
    
#DEFINE 두 비동기 기능 
비동기 DEF의 asyncfunc1 () : 
    인쇄 (이하 "일시 FUNC1") 
    . (1) AWAIT의 asyncio.sleep 
    인쇄 ( "FUNC의 FUNC1", threading.current_thread ()) 
    인쇄 ( 'FUNC1 다시 시작') 
    "FUNC1"을 반환 
    
비동기 DEF의 asyncfunc2 () : 
    인쇄 (이하 "일시 FUNC2") 
    AWAIT의 asyncio.sleep (1.) 
    인쇄 ( "FUNC의 FUNC2", threading.current_thread ()) 
    인쇄 ( 'FUNC2 다시 시작') 
    "FUNC2"를 반환

제어 작업 코 루틴

단일 작업의 코 루틴을 실행

위의 기능, 예를 들어, 난 그냥 당신이 사용할 수있는, () 함수 실행을 asyncfunc1하고 결과를 얻고 싶은 loop.create_task() 호출 할 때 작업 선물, 작업의 객체를 생성하는 방법은 서브 클래스 loop.run_until_complete() 에 의해, 코 루틴 마무리 한 후 나중에 task.result() 코 루틴 기능을 습득 결과를 반환합니다.

비동기 데프 asyncfunc1 () : 
    인쇄 ( "FUNC1을 일시 중지")는 
    asyncio.sleep (1) 기다리고 
    인쇄 ( "FUNC FUNC1"threading.current_thread ()) 
    프린트 ( 'FUNC1 재개') 
    "FUNC1을"반환 

__name __ == "__ main__ 경우 " 
    인쇄 ("메인 글 "threading.current_thread ()) 
    루프 asyncio.get_event_loop = () 
    태스크 = loop.create_task (asyncfunc1 ()) 
    loop.run_until_complete (태스크) 
    인쇄 ("작업 결과가 "task.result ())

출력은

메인 글 <_mainthread (mainthread가 "= 시작"(6140)) = ""> 일시 중단 FUNC1 FUNC FUNC1 <_mainthread (mainthread가 "= 시작"(6140)) = ""> FUNC1 작업 결과를 재개하는 것은 FUNC1

그리고 메인 스레드는 같은 스레드에서 코 루틴 기능을 실행 중입니다.

또한 객체를 작업하는 콜백 메소드를 추가 할 수 있습니다

#coding : GBK의 
asyncio 가져 
오기 시간, SYS의 


비동기 데프 asyncfunc1 () : 
    인쇄 ( "FUNC1을 일시 중지") 
    (1) asyncio.sleep을 기다리고 
    인쇄 ( "FUNC FUNC1", threading.current_thread ()) 
    ( 'FUNC1 다시 시작') 인쇄 
    반환 "FUNC1" 
    
#定义一个回调函数
데프하여 callbackFunc (작업) : 
    인쇄 ( "작업运行结束,它的结果是", task.result ()) 
    
    
의 경우 __name __ == "__ main__" 
    인쇄 ( "메인 스레드에서" , threading.current_thread ()) 
    루프 asyncio.get_event_loop = () 
    태스크 = loop.create_task (asyncfunc1 ()) 
    task.add_done_callback (하여 callbackFunc) 
    loop.run_until_complete (작업)

출력은

메인 글 <_mainthread (mainthread가 "= 시작"을 11,248) = "">

일시 중지 FUNC1

FUNC FUNC1 <_mainthread (mainthread가 "= 시작"을 11,248) = "">

다시 시작 FUNC1

작업의 끝을 실행하여, 그 결과는 다음과 같습니다 FUNC1

loop.run_until_complete 차단 방법은, 그것은 코 루틴이 방법이 끝날 때까지 실행 안에서만 종료 후, 코드 후 실행됩니다.

사실, 당신은 호출 할 수 없습니다 loop.run_until_complete 이 시간 작업 상태 사실, 실행중인 코 루틴 함수에왔다, 작업을 생성, 방법 후에 만 준비하면 이벤트 루프가 실행 시작할 때, 그리고 pending 다음하지 않는, 이벤트 루프를 호출 할 경우, 메인 스레드 마감 이후, 하위 스레드가 같은 코드로 작성된, 파괴됩니다, 코 루틴 기능을 실행합니다

만약 __name __ == "__ main__" 
    인쇄 ( "메인 글"threading.current_thread ()) 
    루프 asyncio.get_event_loop = () 
    태스크 = loop.create_task (asyncfunc1 ()) 
    time.sleep (3)

결과 출력은

메인 글 <_mainthread (mainthread는 "시작 ="6056) = "">

작업이 파괴되었지만 보류 중입니다!

태스크:

CB = test.py:39로하여 callbackFunc ()]>

SYS : 1 : RuntimeWarning : 코 루틴 'asyncfunc1'기다려온되지 않았다

그래서 당신은 코 루틴 기능이 구현되어 있는지 확인하려면, 당신은 위의 작업을 수행하는 이벤트 루프를 호출 할 필요 loop.run_until_complete 는주기가 사실도 사용할 수 있습니다 실행하기 시작하는 것입니다 loop.run_forever() 그 이름에서 알 수 있듯이 항상 실행됩니다,이 기능을. 만 이벤트 루프가 실행 한 후 등록 된 코 루틴이 구현 될 사이클을 사용하지만 경우 loop.run_forever() 가 여기에 백업 할하는 이벤트 루프가있는 stop 방법,주기의 끝, 우리는 개체 작업에 콜백 메소드를 추가 할 수 있습니다 이벤트 루프 호출 할 때 코 루틴 실행 종료 후, stop 전체 사이클을 종료하는 방법을

#coding : GBK의 
asyncio 가져 
오기 시간, SYS의 

비동기 데프 asyncfunc1 () : 
    인쇄 ( "FUNC1을 일시 중지") 
    (1) asyncio.sleep을 기다리고 
    인쇄 ( "FUNC FUNC1", threading.current_thread ()) 
    ( 'FUNC1 다시 시작') 인쇄 
    반환 "FUNC1" 
    
#定义一个回调函数
데프하여 callbackFunc (작업) : 
    인쇄 ( "작업运行结束,它的结果是", task.result ()) 
    loop.stop () 
    
    
경우 __name __ == "__ main__" 
    인쇄 ( "메인 글"threading.current_thread ()) 
    루프 asyncio.get_event_loop = () 
    태스크 = loop.create_task (asyncfunc1 ()) 
    task.add_done_callback (하여 callbackFunc) 
    loop.run_forever ()

사용하는 외에 loop.run_until_complete 방법도 사용될 수있다 asyncio.ensure_future() 위의 코드를 실행하는 방법의 코 루틴을 task = loop.create_task(asyncfunc1()) 하는 task = asyncio.ensure_future(asyncfunc1()) 동일한 결과를 얻을, 그것은, 코 루틴 객체 또는 파라미터의 미래는, 작업 목적은 미래의 서브 태스크로 전달 될 수있다 들어오는 때 미래가 객체를 직접 반환 할 때 그 호출에, 말을하는 것입니다하는 선물을 전달하는 코 루틴 객체이며, 작업 개체를 반환 asyncio.ensure_future() 은 콜백 메소드를 추가 할 수있는 작업 개체를 반환합니다, 나중에 및 (작업이 수행되지 않은 경우 최종 결과는 예외가 발생합니다 방법이라고주의) 결과를 얻기 위해 () 메소드를 task.result 호출 할 수 있습니다.

병렬 코 루틴에서 복수의 태스크

내가 어떻게 작동 않는 동시에이 두 가지 기능을 수행하고 그 반환 값을 받기를 원한다면 나는 정상이 비동기 기능 asyncfunc1 및 asyncfunc2있어?

위의 하나의 코 루틴의 경험을 바탕으로, 우리는 또한 () run_forever에서 실행되는 다음 두 가지 작업주기를 만들기 위해 이벤트를 사용할 수 있습니다, 당신은 작업에 콜백을 추가하고, 결과를 출력 할 수 있습니다.

#coding : GBK 
가져 오기 ASYNCIO의 

# 두 개의 비동기 기능을 정의 
비동기 DEF의 asyncfunc1 () : 
    인쇄 ( "현수 FUNC1") 
    AWAIT의 asyncio.sleep (. 1) 
    인쇄 ( "FUNC의 FUNC1"threading.current_thread을 ()) 
    인쇄 ( '다시 시작 FUNC1 ') 
    반환 "FUNC1" 
    
비동기 DEF의 asyncfunc2 () : 
    인쇄 (이하 "일시 FUNC2") 
    AWAIT의 asyncio.sleep (1). 
    인쇄 ( "FUNC의 FUNC2", threading.current_thread ()) 
    인쇄 (') 'FUNC2 다시 시작 
    "FUNC2"를 반환 

    
# 콜백 함수의 정의 
DEF의하여 callbackFunc (작업) : 
    인쇄 ( "작업 실행의 끝을, 그 결과는 다음과 같습니다", task.result ()) 
    
    
IF __name__ __ == "__ main__"  
    인쇄 ( ""메인 스레드에서, threading.current_thread ())
    루프 = ASYNCIO.get_event_loop () 
    작업 1 = loop.create_task (asyncfunc1 ()) 
    task1.add_done_callback (하여 callbackFunc) 
    task2 = loop.create_task (asyncfunc2 ()) 
    task2.add_done_callback (하여 callbackFunc) 
    loop.run_forever ()

출력은

메인 글 <_mainthread (mainthread는 "시작 ="8040) = "">

일시 중지 FUNC1

일시 중지 FUNC2

FUNC FUNC1 <_mainthread (mainthread는 "시작 ="8040) = "">

다시 시작 FUNC1

FUNC FUNC2 <_mainthread (mainthread는 "시작 ="8040) = "">

다시 시작 FUNC2

작업의 끝을 실행하여, 그 결과는 다음과 같습니다 FUNC1

작업의 끝을 실행하여, 그 결과는 다음과 같습니다 FUNC2

루프로 인해 이번에는 방법을 run_forever라고하고, 정지 메소드를 호출 할 수있는 방법이 없기 때문에 프로그램은 카드를 가지고 있습니다.

이러한 과정은 공동 실행의 복수가 될 수 있지만, 이러한 과정을 복잡 하나, 두 번째는 결과를 복구하는 데 편리하지 않습니다.

asyncio 수집 await를 asyncio.gather는 (*)는 모든 결과를 반환합니다 호출 할 때, 여러 작업 객체를 건네 줄 수있는 방법이있다

새로운 기능을 만들 필요도있다, 그래서만을 기다리고 비동기 DEF 기능에 쓰기 때문에

비동기 DEF 주 () : 
    작업 1 = loop.create_task (asyncfunc1 ()) 
    task1.add_done_callback (하여 callbackFunc) 
    task2 = loop.create_task (asyncfunc2 ()) 
    task2.add_done_callback (하여 callbackFunc) 
    결과 = asyncio.gather 기다리고 (작업 1, task2)     
    프린트 (결과) 
    
비동기 DEF mian2 () 
    결과 = 기다리고 asyncio.gather (asyncfunc1 () asyncfunc2 ()) 
    프린트 (결과)

두 정의는 방법입니다, 하나는 전달 함수는 코 루틴 객체가 작업 개체에 전달되어 수집하는 것입니다. 호출 한 후

만약 __name __ == "__ main__" 
    인쇄 ( "메인 글"threading.current_thread ()) 
    루프 asyncio.get_event_loop = () 
    loop.run_until_complete (주 ()) 또는 메인 2 # ()

결과 출력은

메인 글 <_mainthread (mainthread는 "시작 ="7016) = "">

일시 중지 FUNC1

일시 중지 FUNC2

FUNC FUNC1 <_mainthread (mainthread는 "시작 ="7016) = "">

다시 시작 FUNC1

FUNC FUNC2 <_mainthread (mainthread는 "시작 ="7016) = "">

다시 시작 FUNC2

작업의 끝을 실행하여, 그 결과는 다음과 같습니다 FUNC1

작업의 끝을 실행하여, 그 결과는 다음과 같습니다 FUNC2

[ 'FUNC1', 'FUNC2']

이것은 병렬 코 루틴 회수 및 결과를 달성한다.

이 문서에서는 간단히 다음 동기 코드의 실행을 분석하는 것, 여기에 소개했다.

추천

출처blog.csdn.net/java276582434/article/details/92106788