Pythonã®éåæéä¿¡ï¼asyncioã¢ã¸ã¥ã¼ã«ï¼å ¥éãæ¸ãã¾ãã
ã¯ããã«
éåæå¦çã®ãã¨ããç¥ããªã人åãã«Pythonãããããããã«ç¥ããªã人éãæ¸ãã¾ããããã£ãããã¼ã¯ã¼ããææ³ã«çµã¿è¾¼ã¾ãããã ããç解ãããããããï¼
asyncioã¢ã¸ã¥ã¼ã«ã使ãããã®åºæ¬çãªæ¦å¿µãç解ã§ããããã«ãªã£ã¦ãã¯ããå¤åã
ç°å¢ã¨ãã¦ã¯ Python3.5 以ä¸ãæ³å®ãã¦ãã¾ããã¤ã¾ããawait
ã async
ãã¼ã¯ã¼ãã使ã£ã¦ããã¾ãã
ãããããé¢æ°ãã¡ã½ããã®ä»®å¼æ°ã¯å ¨ãæ¸ãã¦ã¾ãããå¿ è¦æä½éã¯æä¸ã§èª¬æãã¦ãã¾ãããããå®å ¨ã«ç¥ããã人ã¯é©å®ããã¥ã¡ã³ãã®åç §ããé¡ããã¾ãã
主役ã¯ã«ã¼ãã¡ãã
asyncioã®ä¸»å½¹ã¯ã¤ãã³ãã«ã¼ãã§ããã¤ãã³ãã«ã¼ãã¯é ¼ã¾ããä»äºãé çªã«ã©ãã©ãå¦çãã¦ãããããã¯ã¼ã«ã¬ã¤ã§ãã
æ¬è³ªçã«ãç§ãã¡ã¯ã¤ãã³ãã«ã¼ãã«ä»äºãé¢æ°ãªãã¸ã§ã¯ãã®å½¢ã§ä¸ãã¦ããã ãã§ããasyncioã¢ã¸ã¥ã¼ã«ã®å¤§é¨åã¯ãç§ãã¡ãä»äºãé¢æ°ä»¥å¤ã®å½¢ã§ã¤ãã³ãã«ã¼ãã«ä¸ããããã«ããã¾ãï¼ãã¡ããå é¨ã§ã¯é¢æ°ã¨ãã¦ã¤ãã³ãã«ã¼ãã«ä»äºãä¸ãã¾ãï¼ãå¾ã ããã¾ãããã»ã¨ãã©ã®å ´åãç§ãã¡ã¯ã³ã«ã¼ãã³ã¨ããå½¢ã§ä»äºãå®ç¾©ãããããå å·¥ãã¦ãããã¾ãã
ãã¦ããã®èå¿ã®ã¤ãã³ãã«ã¼ãã¯
loop = asyncio.get_event_loop()
ã§æã«å ¥ãã¾ãã
ä»äºã®ä¾é ¼
ã§ã¯ããã¾ãã«ç´ æ´ã§ãããé¢æ°ãªãã¸ã§ã¯ãã¨ãã¦ä»äºãä¸ããæ¹æ³ã¯2ã¤ããã¾ãï¼
call_soon
ã¡ã½ããcall_later
ã¡ã½ãã
loop.call_soon(callback, *args)
ã¯ãã¤ãã³ãã«ã¼ãã« callback ã¨ããé¢æ°ãªãä»äºããã®å¼æ° args
ã¨ã¨ãã«æ¸¡ãã¾ãã
ä»äºã®éå§æéã決ãããã¨ãã§ãã¾ããloop.call_later(time, callback, *args)
ã¯ãä»ãã time ç§å¾ã®æç¹ã« callback ãå¼ã¶ããã«ã¤ãã³ãã«ã¼ãã«ãé¡ããã¾ãããã ãããã以åã®ä»äºã«æéãããã£ã¦ããå ´åã¯ããã®ä»äºã«æãä»ããã®ã¯éå§æé以éã«ãªãã®ã§æ³¨æã§ãã
ã¤ãã³ãã«ã¼ãã®å®è¡
è²ã ã¨ã¤ãã³ãã«ã¼ãã«ä»äºãé ¼ã¿ããã ãã¨ã¯ãã¤ãã³ãã«ã¼ããå®è¡ãã¦ä»äºãå¦çãã¦ãã£ã¦ãããã¾ãããï¼
loop.run_forever()
ã«ãã£ã¦ãã«ã¼ããæ°¸é ã«å®è¡ãã¾ãã
ãã ããæ°¸é ã«å®è¡ãããã¨å°ãã®ã§ããªãããã®å½¢ã§ã¤ãã³ãã«ã¼ããæ¢ããããã«ãã¾ããããã¤ãã³ãã«ã¼ãã®åæ¢ã¯ loop.stop()
ã§è¡ãã¾ããloop.stop()
ãå¼ã°ããã¨ãã¤ãã³ãã«ã¼ãã¯ãã®æç¹ã«ç©ãã§ããä»äºããã¹ã¦çµãããã¦ããåæ¢ãã¾ãããã ãããã®ä»äºãããªãéä¸ã§æ°ãã«è¿½å ãããä»äºã¯ã次åã®å®è¡ã®ã¨ãã¾ã§å»¶æããã¾ããæ®æ¥ä¸ã«åºã¦ããæ°ããä»äºã¯ã次ã®åºç¤¾æ¥ã«ããã£ã¦ãã¨ã§ããã
ã¨ããããã§ã
loop.call_soon(loop.stop)
ã§æå¾ã®ä»äºã¨ãã¦ã«ã¼ãã®åæ¢ãããã- æå¾ã®ä»äºã¨ãã¦æ¸¡ããé¢æ°ã®ä¸èº«ã§
loop.stop()
ãå¼ã¶
ãªã©ããã¦ã«ã¼ãã«é社å½ä»¤ãåºãã¦ããã¾ããããåæ¢ããã«ã¼ãã¯
loop.close()
ã§éãã¦ããã¾ãããã
ä¾
ããã¥ã¡ã³ãã«ããä¾ãå°ããã»ãã®å°ãã ãå¤ãããã®ã§ãï¼
import asyncio import datetime def display_date(end_time, loop): print(datetime.datetime.now()) if (loop.time() + 1.0) < end_time: loop.call_later(1, display_date, end_time, loop) else: loop.call_soon(loop.stop) # åã« loop.stop() ã§ããã loop = asyncio.get_event_loop() # Schedule the first call to display_date() end_time = loop.time() + 5.0 loop.call_soon(display_date, end_time, loop) # Blocking call interrupted by loop.stop() loop.run_forever() loop.close()
display_date
ã2ã¤ã®ä»äºããã¦ãã¾ãï¼
- ä»ã®æå»ã®è¡¨ç¤º
- 次ã®ä»äºã®è¿½å ï¼ããä¸å
display_date
ããããããåæ¢ããããï¼
ã«ã¼ããèµ°ãããæç¹ã§ã¯ãã«ã¼ãã«ã¯1ã¤ã®ä»äºããä¸ãã¦ãã¾ãããããã®ä»äºã®ä¸ã§æ¬¡ã®ä»äºãã«ã¼ãã«ä¸ãã¦ããã¨ããæ§å³ã§ãã
ããããé¢æ°ã渡ãã®ãããããããã¾ããï¼
def display_date2(loop): print(datetime.datetime.now()) try: loop.call_later(1, display_date, end_time, loop) except KeyboardInterrupt: loop.stop()
Ctrl + C
ã§ã«ã¼ããéªéããªãéããæ°¸é ã«ã«ã¼ãã¯æå»ã表示ãã¤ã¥ãã¾ãã
ä»äºã®ãã£ã³ã»ã«
call_soon
ãcall_later
ã¡ã½ãã㯠Handleã¯ã©ã¹ã®ã¤ã³ã¹ã¿ã³ã¹ãè¿ãã¾ãã
ãã®ä»äºããã£ã³ã»ã«ãããå ´åã¯ããã®ãã³ãã«ã®cancel()
ã¡ã½ããã使ãã¾ãã
asyncio ã使ãã«ããã£ã¦ãç§ãã¡ããããã¨ã¯
- ã¤ãã³ãã«ã¼ãã®åå¾ï¼
loop = asyncio.get_event_loop()
ï¼ - ã¤ãã³ãã«ã¼ãã¸ã®ã¹ã±ã¸ã¥ã¼ãªã³ã°ï¼
loop.call_soon(callback)
ã¨ãï¼ - ã¤ãã³ãã«ã¼ãã®å®è¡ï¼
loop.run_forever()
ãªã©ï¼ - ã¤ãã³ãã«ã¼ãã®åæ¢ï¼
loop.stop()
ï¼ - ã¤ãã³ãã«ã¼ããéããï¼
loop.close()
ï¼
ã¨ãããã¨ã§ãã
ãªãããããã«ã¼ãã¡ããã«ä»äºããããã®ã
ããã¾ã§ã«ãããã¨ã ããè¦ãã°ãç§ãã¡ããµã¤ãã«é¢æ°ãé 次å®è¡ãã¦ããããã«ã³ã¼ããæ¸ãã®ã¨ä½ãå¤ããã¾ãããcall_later
ã ã£ã¦ãtime.sleep()
ã§ãã®æéã ãå¾
ã£ã¦ãã次ã®é¢æ°ãå¼ã³åºãã°ããã ããããªãã§ããï¼
ç§ãã¡ããããããã¨ãã«ã¼ãã«ä»äºã¨ãã¦ããããæ大ã®çç±ã¯ ã«ã¼ãã¯ç§ãã¡ãã³ã¼ããé 次å®è¡ãããããå¨ç¨ã«ä»äºããã¦ããã ããã§ããå¨ç¨ã£ã¦ï¼
ã¨ããã®ããã«ã¼ãã¯ããããã³ã°I/Oã«ã¤ãã¦ä¸æãããªãè¡ãç¥ã£ã¦ãããã§ãã
I/Oã¯ã¨ãããã¨ãã¦ãããããã³ã°ã¨ããã®ã¯æ¥å¸¸çæ´»ã§ãããééããç§ãã¡ãã¤ã©ã¤ã©ããã¦ãããã¨ã§ããããããããªããä½ããå¾ ã£ã¦ããéãå¾ ã¤ãã¨ä»¥å¤ã«ãããªãã¨ãã§ããªãã¨ããããªãã¯ããããã³ã°ããã¦ãã¾ãï¼å¸å½¹æã®é·ãé·ãå¦çæéã®éãããªãã«ã§ãããã¨ã¨è¨ãã°éãç¼å·®ãã§äºåå¡ã«ãã¬ãã·ã£ã¼ãä¸ãããã¨ãããã§ãããã
ã§ãããããå¦çãçµãã£ããã±ã¼ã¿ã¤ã«é£çµ¡ããããã¨è¨ã£ã¦ããããã©ãã§ãããï¼ãã®éã«ããªãã¯ä»æ¥çºå£²ã®ãæ°ã«å ¥ãã®éèªãè²·ãã«æ¸åºã¸è¡ããä»æåã®å®¶è³ãæ¯è¾¼ã¿ã家ã«ãªãã£ãææ¿å ·ã調éããæ¸è³ãã¬ãããã¹ãã«å ¥ããå«è¶åºã§ã³ã¼ãã¼ã飲ã¿ãªããasyncioã«é¢ããè¨äºãæ¸ããâ¦â¦ããããå®ã«å¾ ã¡æéãææ義ã«éãããã¨ãã§ãããã¨ã§ãããï¼
ãããã±ã¼ã¿ã¤ã«é£çµ¡ããããªãã£ã¦ããããã¦åä»çªå·ã渡ãã¦ãããã°ãä»äºãï¼ã¤ããªãã¦ã¯å¸å½¹æã«è¡ã£ã¦èªåã®å¦çãçµãã£ã¦ãªãã確èªããã¾ã ãªãä»ã®ãã¨ããã«ããã¨ãããããªãã¨ãã§ãã¾ãããããã¡ãã¡å¸å½¹æã«è¡ããªãã¨ãããªãã®ãé¢åã§ãããããã¹ããã¨ãå¸å½¹æã®ããè¿æã§æ¸ããããªããã¾ãååã§ãããã
ã¤ãã³ãã«ã¼ãã¯ãã¾ãã«I/Oï¼ã¨ä¸é¨ã®äºæï¼ã«é¢ãã¦ãã®ãããªå¨ç¨ãªãã¨ãã§ããã®ã§ããæéã®ãããI/Oã®åã§ãã¤ã¾ã§ãçªã£ç«ã£ã¦ãªãã§ãã¤ãã³ãã«ã¼ãã¯ãã®ãã§ãã¯ãä»ã®ä»äºã®å¾ã«åãã次ã®ä»äºã«åããããã¾ãã
調ã¹ãã¨ããã«ããã¨ãããã¦åºå¥ããã®ã§ããã°ãã±ã¼ã¿ã¤ã«é£çµ¡ãã¦ããããããªæ¹å¼ããéåæI/Oããåä»çªå·ãããã£ã¦åº¦ã 確èªãã«ãããããªæ¹å¼ãããã³ããããã³ã°I/Oãã¨å¼ã¶ããã§ããã¡ãªã¿ã«æé«ã«ã¹ãã¬ã¹ã®ãã¾ãä¾ã®ã¢ã¬ã¯ãåæI/Oãããããããã³ã°I/Oãã¨å¼ã³ã¾ãã
asyncioã¢ã¸ã¥ã¼ã«ã®ã¤ãã³ãã«ã¼ãã¯åºæ¬çã«ã¯ãã³ããããã³ã°ã«ä»äºãããªãã¾ããããå ´åã¯éåæçã«ãæ¯ãèãã¾ããããããã«ããã¤ãã³ãã«ã¼ãã¯ä»äºãç¡é§ãªãå¦çãããã¨ãã¦ããã¾ãã
ã«ã¼ãã¡ããã®ã¹ãã«ãçãã
ä»ã¾ã§ã®ããæ¹ã ã¨ã«ã¼ãã¡ããã®å¨ç¨ããã¾ãã§çãããã¦ãªãã®ã¯æããã§ããä»ã¾ã§ã®ãé¢æ°ãä»äºã¨ãã¦æ¸¡ãã¨ããç´ æ´ãªããããã§ã¯ã«ã¼ãã¡ããã¯ã空ãæéããä¸æãè¦ã¤ããããªãã®ã§ããããã§ãè¨ãããããªã§ããã次ã«ã«ã¼ãã¡ãããå¨ç¨ã«åãåãããããªä»äºã®ä½ãæ¹ãå¦ã³ã¾ãããã
â¦ã¨ããã®æºåã¨ãã¦ãã¡ãã£ã¨ä¸æè°ãªãªãã¸ã§ã¯ããFutureãªãã¸ã§ã¯ãã«ã¤ãã¦å¦ã³ã¾ãããã
Future
Futureãªãã¸ã§ã¯ãã¯é«ã¬ã¤ã¤ã¼ãªä¸¦åå¦çã¢ã¸ã¥ã¼ã« concurrent.futures ã«ããããªãã¸ã§ã¯ãã§ãã
Futureãªãã¸ã§ã¯ãã¯ãç°¡åã«ããã° çµæã®ä»£ããã¨ãªã ãªãã¸ã§ã¯ãã§ããããå¤ã渡ããããªå¦çããã£ãã¨ãã¦ãéä¿¡å´ã¯ã¨ããããFutureãªãã¸ã§ã¯ããåä¿¡å´ã«æ¸¡ããéä¿¡å´ã¯å¦çãçµãã次第ãã®Futureãªãã¸ã§ã¯ãã«å¤ãæ¾ãè¾¼ã¿ã¾ããåä¿¡å´ã¯ãFutureãªãã¸ã§ã¯ãã®ç¶æ ãå®äºã«ãªã次第ãå¤ãåãåºãã¦ç¶ãã®å¦çã«ä½¿ããã¨ãã§ãã¾ãã
ã¤ãã³ãã«ã¼ãã®å¨ç¨ãã¯ç¢ºãã«ãã®Futureãªãã¸ã§ã¯ãã«å ãã¨ããã大ããã®ã§ãããããã«ã¤ãã¦ã¯ããå°ãå¾ã§è¦ã¦ããã¾ãããã
ãã¦ãFutureãªãã¸ã§ã¯ãã«å¯¾ãã¦ã§ãããã¨ã¯ã大ã¾ãã«4ã¤ã§ãï¼
- ç¶æ ã®ç¢ºèªï¼done, cancelledï¼
- å¤ã®åãåºãï¼result, exceptionï¼
- å®äºï¼å¤ã®è¨å®ã»ãã£ã³ã»ã«ï¼ï¼set_result, set_exception, cancelï¼
- ã³ã¼ã«ããã¯ã®è¨å®ï¼add_done_callback, remove_done_callback)
Futureã¤ã³ã¹ã¿ã³ã¹ã«ã¨ã£ã¦ “done” ã¨ã¯ãçµæãä¾å¤ãè¨å®ããããã¨ãæå³ãã¾ããã³ã¼ã«ããã¯ã¯Futureãªãã¸ã§ã¯ããå®äºããã¨ãã«å¼ã³åºããã¾ãã
Futureãªãã¸ã§ã¯ãããã£ã³ã»ã«ãããã¨ãcancelled å±æ§ã True ã«ãªããã³ã¼ã«ããã¯ãå¼ã°ãã¾ããã
Futureãªãã¸ã§ã¯ããããè¼ããããã®ã¨ãã¦ããã¦ããã®ã¯ãå®äºæã³ã¼ã«ããã¯ã®æ©è½ã§ãï¼ã³ã¼ã«ããã¯ã¯ãFutureãªãã¸ã§ã¯ããå®äºããã¨ãã«å¼ã°ããå¦çã§ãããã®ã³ã¼ã«ããã¯ã«ã¯Futureãªãã¸ã§ã¯ãèªèº«ã®ã¿ãå¼æ°ã¨ãã¦åããããªé¢æ°ï¼ãããã¯ä¸è¬ã«ãã®ãããªã³ã¼ã©ãã«ãªãã¸ã§ã¯ãï¼ãæå®ãã¾ãã
ããã©ã«ããªFutureãªãã¸ã§ã¯ãã¯loop.create_future()
ã§ä½ãã¾ããFutureãªãã¸ã§ã¯ããä½ã£ãå¾ããããã¯èª°ããã渡ãããå¾ãã³ã¼ã«ããã¯ãè¨å®ãã¦ã好ã¿ã®Futureãªãã¸ã§ã¯ããä½ãä¸ãã¾ãããï¼
Futureãªãã¸ã§ã¯ããå©ç¨ããä¸æãæ¹æ³ã¯2ã¤ããã¾ããã²ã¨ã¤ã¯ãå®æçã«Futureãªãã¸ã§ã¯ãã®æ§åãè¦ã¦ãããããã«ã¤ãã³ãã«ã¼ãã«ä»äºãé ¼ãæ¹æ³ã§ããã¾ã å®äºãã¦ããªãããã§ããã°ãåãä»äºãcall_soon
ãã¦ããã°ãããã¦ããã¾ãã¤ãã³ãã«ã¼ãã«è¦ã¦ãããããã«ãã¾ãã
ããã²ã¨ã¤ã¯ãæããåãã£ã¦ããã¨ã¯æãã¾ãããå®äºæã³ã¼ã«ããã¯ã使ãæ¹æ³ã§ããFutureãªãã¸ã§ã¯ãã«ãFutureãªãã¸ã§ã¯ããå®äºãã¦ä»¥éã«ãããã£ãä»äºå 容ãã³ã¼ã«ããã¯é¢æ°ã¨ãã¦æ¸¡ãã¦ããã¾ããããããã¨Futureãªãã¸ã§ã¯ãã¯èªåã«å¤ãè¨å®ãããã¨ãã«ãã¤ãã³ãã«ã¼ãã«ãã®ä»äºãé ¼ã¿ã¾ããã¾ãã«ã±ã¼ã¿ã¤ã«é£çµ¡ããããã«ï¼ã¤ãã³ãã«ã¼ãã¯ãã®ä»äºãã¹ã±ã¸ã¥ã¼ã«ã«çµã¿è¾¼ãã§ããã§ãããã§ããã
å®äºæã³ã¼ã«ããã¯ãç¨ããæ¹ãæç¶ã¹ã¿ã¤ãªãã·ã¥ã«ã¿ãã¾ãããåè ã®æ¹ã§ããã§ããªããã¨ãããã¾ããï¼ã¤ã®æ¹æ³ã使ãåããããããã«ãã¾ãããã
ä¾
Futureãªãã¸ã§ã¯ããå©ç¨ãã便å©ãªæ©è½ã®ã²ã¨ã¤ããã¤ãã³ãã«ã¼ãã®å®è¡ã®ä»æ¹ã®ã²ã¨ã¤ãloop.run_until_complete(future)
ã§ããloop.run_forever()
ã¨ç°ãªããå¼æ°ã®Futureãªãã¸ã§ã¯ããå®äºããã¨ã¤ãã³ãã«ã¼ããåæ¢ãã¾ãã
ä¼¼ããããªæåã®ãã®ãèªåã§ãä½ãããã§ããFutureãªãã¸ã§ã¯ããå®äºããã¨ãã«ã«ã¼ããåæ¢ãããã°ãããã§ããããFutureãªãã¸ã§ã¯ãã«ãã®ãããªã³ã¼ã«ããã¯ãä¸ãã¦ããã°ããã§ãããï¼
loop = asyncio.get_event_loop()
future = loop.create_future()
future.add_done_callback(loop.stop)
... # æºå
loop.run_forever()
å®ã¯ãloop.run_until_complete()
ã«ã¯ã¾ã é ãããæ©è½ãããã®ã§ãããããã¯å¾ã
æããã«ãªãã§ããããã§ããããä¸ã®ã³ã¼ãã¯ãã®ã¡ã½ããã®å®å
¨çã§ã¯ããã¾ãããæ®å¿µï¼ãããããããããªã¡ãããªå®è£
ãããªãã¦å®å¿ï¼
ã¾ãã¯ç°¡åãªä¾ããï¼
# coding=utf-8 import asyncio def set_result_to_future(value, future): if not future.done(): future.set_result(value) loop = asyncio.get_event_loop() future = loop.create_future() loop.call_soon(set_result_to_future, "DONE!", future) result = loop.run_until_complete(future) assert(future.result() == result) print(result) loop.close()
ããå®ã¯loop.run_until_complete(future)
ã¯å®äºããFutureãªãã¸ã§ã¯ãã®çµæã®å¤ãããªãã¡future.result()
ãè¿ãã¦ããã¾ãããã¡ããä»åã®å ´åã ã¨ãFutureãªãã¸ã§ã¯ãã¯æå
ã«ããã®ã§ãããããçµæãåãåºãã¦ãæ§ãã¾ããã
ããã¾ãé¢ç½ã¿ããªãã®ã§ãããå°ãåããã¦ã¿ã¾ãããï¼
# coding=utf-8 import asyncio import sys from random import randint def random_hit(future, n_upper, count=1, loop=None): if loop is None: loop = asyncio.get_event_loop() value = randint(1, n_upper) if value == 1: future.set_result(count) else: count += 1 loop.call_soon(random_hit, future, n_upper, count, loop) def _callback(future): print("DONE!") try: n = int(sys.argv[1]) except IndexError: print("Input an integer.") n = int(input()) if n < 1: n = 1 loop = asyncio.get_event_loop() future = loop.create_future() future.add_done_callback(_callback) loop.call_soon(random_hit, future, n) result = loop.run_until_complete(future) print(result) loop.close()
æºåã¨ãã¦ã¯ã
- n ã«éè² æ´æ°ãã»ãã
- ã«ã¼ããåå¾
- Futureãªãã¸ã§ã¯ããã¤ãããããã«
_callback
ãã³ã¼ã«ããã¯ã¨ãã¦è¿½å - ã«ã¼ãã«
random_hit
é¢æ°ã future 㨠n ãå¼æ°ã¨ãã¦ã¨ãã«ä¸ãã
ã¨ãªãã¾ããã«ã¼ãã®å¯ä¸ã®ãä»äºã¯random_hit
ã§ããããã¯ä¹±æ°å¤ãåå¾ããããã1ãªãFutureãªãã¸ã§ã¯ãã«count
ã®å¤ãã»ãããããã§ãªããªãcount
ã+1ããå度åãæ¡ä»¶ã§random_hit
ãã«ã¼ãã«ä»äºãã¦ä¸ãã¾ãã
ç¹ã«ãrandom_hit
ã¯loop
ãä¸ããããªãã£ãã¨ãã«èªåã§asyncio.get_event_loop()
ã«ãã£ã¦ã¤ãã³ãã«ã¼ããåå¾ãã¦ããã¨ããã«æ³¨æãã¦ãã ãããã¤ãã³ãã«ã¼ãã¯1ã¹ã¬ããã«1ã¤ä¸ããããã®ã§ãããã§å¾ãããã¤ãã³ãã«ã¼ãã¯æåã«åå¾ãããã®ã¨åãã§ãã
ããã£ã¨ãæ°æã¡ã¯ãããã¾ããããã ã¨ãåç´ã«é¢æ°ãå帰ãããã®ã¨ä½ãéããã ã£ã¦æãã¾ããããããã²ã¨å·¥å¤«ãã¦ã¿ã¾ãããã
# coding=utf-8 import asyncio import sys from random import randint def random_hit(future, n_upper, count=1, loop=None): if loop is None: loop = asyncio.get_event_loop() value = randint(1, n_upper) if value == n_upper: print("Hit!") # add future.set_result(count) else: print("Not yet.") # add count += 1 loop.call_soon(random_hit, future, n_upper, count, loop) def eternal_hello(loop): # add print("Hello!") loop.call_soon(eternal_hello, loop) def _callback(future): print("DONE!") loop = asyncio.get_event_loop() try: n = int(sys.argv[1]) except IndexError: print("Input an integer.") n = int(input()) if n < 1: n = 1 loop = asyncio.get_event_loop() future = loop.create_future() future.add_done_callback(_callback) loop.call_soon(random_hit, future, n) loop.call_soon(eternal_hello, loop) # add result = loop.run_until_complete(future) print(result) loop.close() # > python future.py 10 # Not yet. # Hello! # Hit! # Hello! # DONE! # Hello! # 2
ãã¾ã大ããªå¤ã¯å
¥åããªãããã«ï¼ããã¼å°çã®ã¯ãã¾ãã§ãï¼ããã£ãã¨ã®éãã¯ã"Hello!“ ã¨æ¨æ¶ãã¦ãã¾ããã®ä»äºãã¤ãã³ãã«ã¼ãã«æ¼ãä»ããã¦ã«ãµã¤ãã¤ããããã¨ã¨ããã¨ã¯å°ãprintæãå¢ããããããã§ãããã®ä»äºãrandom_hit
ã®ä»äºä¾é ¼ã®æ¬¡ã®è¡ã§é ¼ã¿ã¾ãããä¸å¿è¨ã£ã¦ããã¨ãè¤æ°ã®ä»äºãããå ´åã¯å
ã«è¿½å ããã»ãããå¦çãã¦ããã¾ãï¼FIFOã£ã¦ãã¤ã§ããï¼ã
èå³æ·±ããã¨ã«ãåã«random_hit
ãå帰ãããã®ã¨éã£ã¦ãã¾ã Hit! ãã¦ããªãã«ãããããããeternal_hello
ãæ¨æ¶ãã¦ãã¾ããï¼ã¨ã¯ããããããªä¸æè°ã§ãããã¾ãããããä»äºã®å¦çã¯FIFOã§ãrandom_hit
ã®æ¬¡ã®ä»äºã¯å
ç´ã®eternal_hello
ã®å¾ã«è¡ãããã¯ãã§ãããã
Hit! ãã¦ããå®éã«ã¤ãã³ãã«ã¼ããåæ¢ããã¾ã§ã®æåãå°ãè¦ã¦ã¿ã¾ããããHello! DONE! Hello! ã¨ç¶ããããã¦çµæãåºåããã¦ãã¾ããç¹ã«é©ããã¨ã§ãããã¾ããããFutureãªãã¸ã§ã¯ãã«è¿½å ããå®äºæã³ã¼ã«ããã¯ã¯ãå¤ãè¨å®ãããã¨ãã«ãä»äºã¨ãã¦ã¤ãã³ãã«ã¼ãã«æ¼ãä»ãããã¾ããrun_until_complete()
ã¯å
é¨ã§loop.stop()
ãå¼ã¶ã¨ããã¾ãããããããFutureãªãã¸ã§ã¯ãã®å®äºæã³ã¼ã«ããã¯ã¨ãã¦å¼ã°ãã¾ããã¤ã¾ããçç¸ã¯ãããªãã¾ãï¼
- Hit!ï¼ãã®ã¨ãã«Futureãªãã¸ã§ã¯ãã¯å®äºããã³ã¼ã«ããã¯ãã¤ãã³ãã«ã¼ãã«ä»äºã¨ãã¦æ¸¡ã
- æåã®Hello!ï¼ã³ã¼ã«ããã¯ããå
ç´ã®
eternal_hello
ãæ¨æ¶ããã¾ãæ¨æ¶ã®ä»äºãæ¼ãä»ãã - DONE!ï¼å ç´ã®ä»äºããã¹ã¦çµãããå®äºæã³ã¼ã«ããã¯ãå®è¡ããã
- ä¸é£ã®å®äºæã³ã¼ã«ããã¯ã®æå¾ã®ã¿ã¤ãã³ã°ã§
loop.stop()
ãå¼ã°ããã以ä¸ã¯æ®æ¥ã - 2çªç®ã®ã¨ããã§æ¼ãä»ããããæ¨æ¶ã®ä»äºãæ®æ¥ã¨ãã¦ããªãããã®ã¨ãçããæ°ããªæ¨æ¶ã®ä»äºã¯æ¬¡åå®è¡æã«æã¡è¶ãã
- æ®æ¥ãããï¼ã¤ãã³ãã«ã¼ãã¯ç¡é§ãªæ®æ¥ãããã«ã¨ã£ã¨ã¨å¸°ãã®ã§ãã£ãã
asyncioã¢ã¸ã¥ã¼ã«ããã¤ãã³ãã«ã¼ãã«ä»äºãä¾é ¼ãã¦ãããã¨ããå½¢ã§åãã¦ããã¨ããã®ãåããã¾ããã
æå¾ã®ä¾ã§ã¯ãã»ãã®å°ãã ãã§ããã¤ãã³ãã«ã¼ãã®å¨ç¨ããå£éè¦ãã¾ãããã§ãã¾ã ãä»äºãä¸æãã¦å¥ã®ä»äºã«åãããããã¨ããå¨ç¨ãã®çé«ã¯ãç®ã«ãããã¦ãã¾ãããããããã®ã¯ããç§ãã¡ã¯æªã ããããã風ãªå¦çãã§ãããããªå½¢ã®ä»äºãã«ã¼ãã¡ããã«ä¸ãã¦ããªãããã§ããããããã«ã¼ãã¡ããã®æ¬é ãè¦ãããã§ããï¼
ã³ã«ã¼ãã³ã¨ã¿ã¹ã¯
ã次ã¯ã³ã«ã¼ãã³ã§ããã³ã«ã¼ãã³ã¯ã¸ã§ãã¬ã¼ã¿ãå®ç¾©ããã¨ãã¨åãããã«ãé¢æ°å®ç¾©ã«è¿ãå½¢ã§æ¸ãã¾ããPython3.5ãããã³ã«ã¼ãã³å®ç¾©ã®ææ³ãçµã¿è¾¼ã¾ãã¾ããï¼
async def hello(): print("Hello!")
ãã®ã¨ããhello()
ã¯ã³ã«ã¼ãã³ãªãã¸ã§ã¯ãã§ããã¸ã§ãã¬ã¼ã¿ã¨ä¼¼ã¦ã¾ãã*1ã
ã³ã«ã¼ãã³ã¨ããã®ã¯ãã¾ãã« ã¤ãã³ãã«ã¼ãã«ãå¾ ã¡æéãã©ãã§çºçãããããæãã¦ããããã é¢æ°ã¿ãããªãã®ã§ãã
ã¸ã§ãã¬ã¼ã¿ã¨ä¼¼ã¦ããã¨ãããããä¸ã¤ããã¾ããã¸ã§ãã¬ã¼ã¿ã§ã¯yield from [generator]
ã«ãã£ã¦ãå¥ã®ã¸ã§ãã¬ã¼ã¿ããã§ã¼ã³ãããã¨ãã§ãã¾ããããåæ§ã«ã³ã«ã¼ãã³ã¯await [coroutine]
ã«ãã£ã¦ã³ã«ã¼ãã³ããã§ã¼ã³ãããã¨ãã§ãã¾ãã
ã³ã«ã¼ãã³ãã§ã¼ã³ã¨ãã¦ã®å½¹å²ã大äºã§ãããawait
ã®ããéè¦ãªå½¹å²ã¯ãawait [future]
ã¨ããå½¢å¼ã§ããã¤ã¾ããawait
ã®å¾ã«ã¯Futureãªãã¸ã§ã¯ããç½®ããããã§ãããã¾ãã«ãã®å½¢å¼ããã ã¤ãã³ãã«ã¼ãã«ã¨ã£ã¦ã®ãå¾
ã¡æéãã®å° ã«ãªãã¾ãã
é ã追ã£ã¦è©±ãã¾ããããã¾ããã¤ãã³ãã«ã¼ãã«ã³ã«ã¼ãã³ãä»äºã¨ãã¦æ¸¡ãã«ã¯ãé¢æ°ã®ã¨ãã¨ã¯ç°ãªãæé ãè¸ã¿ã¾ããã³ã«ã¼ãã³ã¯ãFutureã®ãµãã¯ã©ã¹ã§ããTaskãªãã¸ã§ã¯ãã«ããã¾ãã¦ãã¤ãã³ãã«ã¼ãã¨é¢ããåãããã¡ã¾ããTaskãªãã¸ã§ã¯ãã®ä½ãæ¹ã¯2ã¤ããã¾ãï¼
loop.create_task(coroutine)
asyncio.ensure_future(coroutine_or_future)
ensure_future
ã«Futureãªãã¸ã§ã¯ãã渡ããå ´åã¯ããã®ãªãã¸ã§ã¯ãããã®ã¾ã¾è¿ã£ã¦ãã¾ãï¼Taskãªãã¸ã§ã¯ãã«ã¯ãªããªããã¨ã«æ³¨æï¼ï¼ã
ã¾ããloop.run_until_complete()
ã«ã¯ã³ã«ã¼ãã³ã渡ããã¨ãã§ãã¾ãããã®ã¨ããã³ã«ã¼ãã³ã¯å
é¨ã§ensure_future()
ã«ãã£ã¦Taskãªãã¸ã§ã¯ãåããã¾ãã
ã¨ããããã§ãTaskãªãã¸ã§ã¯ããä½ãã¨ãã«ã¯ã³ã«ã¼ãã³ã渡ãã¾ããTaskãªãã¸ã§ã¯ãã¯ãã®ã¨ãã«ãã¿ã¹ã¯ã®ã¹ããããã¨ããä»äºãï¼ä»ã¾ã§ãã£ã¦ããããã«call_soon
ã使ã£ã¦ï¼ã¤ãã³ãã«ã¼ãã«é ¼ã¿ã¾ãã
ãã¿ã¹ã¯ã®ã¹ããããã®ä»äºå
容ã¯æ¬¡ã®éãã§ãï¼ã¾ããã³ã«ã¼ãã³ãawait [Future]
ã«ã¶ã¤ããã¾ã§é²ãã¾ããã³ã«ã¼ãã³ã«Futureãªãã¸ã§ã¯ãã¸ã®awaitããªãã£ãå ´åã¯ããµã¤ãã«ã³ã«ã¼ãã³ã®æå¾ã¾ã§å®è¡ããããã®è¿ãå¤ãTaskãªãã¸ã§ã¯ãã®çµæã¨ãã¦è¨å®ãããå®äºãã¾ãï¼Taskã¯Futureã®ãµãã¯ã©ã¹ã§ãããã¨ã«æ³¨æï¼ããããFutureãªãã¸ã§ã¯ãã¸ã®awaitããã£ãå ´åãã³ã«ã¼ãã³ã¯ã¸ã§ãã¬ã¼ã¿ã®yield
ããããããã®æç¹ã§ä¸æ¦åæ¢ãã¾ããããã¦ããã®Futureãªãã¸ã§ã¯ãã«å®äºæã³ã¼ã«ããã¯ã¨ãã¦ãã¿ã¹ã¯ã®ã¹ããããã追å ãã¾ãã次åãã³ã«ã¼ãã³ã¯ä¸æ¦åæ¢ããã¨ããããFutureãªãã¸ã§ã¯ãã®çµæãåãåã£ã¦åéãã¾ãã
ããããã¿ã¹ã¯ã®ã¹ããããã¨ããä»äºã®æ¦è¦ã§ãããã®å¦æã®ä»çµã¿ã¯ããããåããã«ãªããã¨æãã¾ããã¾ããTaskãªãã¸ã§ã¯ãã¯ãFutureãªãã¸ã§ã¯ãã®å®äºæã³ã¼ã«ããã¯ã¨ãã¦ãã¿ã¹ã¯ã®ã¹ãããããä»äºã¨ãã¦ä¾é ¼ãããªãéããã¤ãã³ãã«ã¼ãã触ããã¨ã¯ããã¾ããï¼ã¤ã¾ããå¦çã¯å 延ã°ãããã ããã§ãããã®Taskãªãã¸ã§ã¯ãã®ç¶ãã¯ãFutureãªãã¸ã§ã¯ããå®äºããªãã¨ã©ããããã¨ãã§ããªãããã§ããããããã¯å®ã«çã«ããªã£ã¦ãã¾ãã
ä¾
ä¾ã¨ãã¦ãawait対象ã¨ãã¦ãã使ãããasyncio.sleep
ã¨ä¼¼ããããªã³ã«ã¼ãã³ãæ¸ãã¦ã¿ã¾ãããããã®ã³ã«ã¼ãã³ã¯ãdelay ç§ã ãåããæ¢ããã®ã¡ãresultãè¿ãã¾ãï¼
import asyncio async def sleep(delay, result=None, *, loop=None): if delay == 0: return result if loop is None: loop = asyncio.get_event_loop() future = loop.create_future() h = loop.call_later(delay, future.set_result, result) try: return (await future) finally: h.cancel()
ãã®ã³ã«ã¼ãã³ã¯å
é¨ã§Futureãªãã¸ã§ã¯ããã¤ãããdelayç§å¾ã«resultããã®Futureãªãã¸ã§ã¯ãã«ã»ããããããcall_later
ãã¦ãã¾ãããããããawait future
ãããã¨ã§ããã®ã³ã«ã¼ãã³ï¼ã®Taskãªãã¸ã§ã¯ãï¼ã®å¦çã future ãå®äºããã¾ã§ã¤ãã³ãã«ã¼ãããé ããã¾ããfutureã®å®äºã¯ãã¡ãããdelayç§å¾ã«å®äºãã¾ãï¼
å®éã«asyncio.sleep
ã使ã£ã¦ã¿ã¾ãããã以ä¸ã®ä¾ã¯å²ã¨ã©ãã§ã§ãè¦ããã®ã§ãã
# coding=utf-8 import asyncio import sys from random import randint async def boring_counting(id_, n): for i in range(n): print("eh, I am {}. {} :(".format(id_, i)) await asyncio.sleep(0.2) print("FINISH! by {} :)".format(id_)) def get_input(): try: n = int(sys.argv[1]) except IndexError: print("Input an integer.") n = int(input()) if n < 1: n = 1 return n n = get_input() loop = asyncio.get_event_loop() futures = set() for i in range(5): futures.add(boring_counting(i, n)) loop.run_until_complete(asyncio.wait(futures)) loop.close() # > python future4.py 3 # eh, I am 0. 0 :( # eh, I am 1. 0 :( # eh, I am 2. 0 :( # eh, I am 3. 0 :( # eh, I am 4. 0 :( # eh, I am 0. 1 :( # eh, I am 2. 1 :( # eh, I am 4. 1 :( # eh, I am 1. 1 :( # eh, I am 3. 1 :( # eh, I am 0. 2 :( # eh, I am 4. 2 :( # eh, I am 3. 2 :( # eh, I am 2. 2 :( # eh, I am 1. 2 :( # FINISH! by 0 :) # FINISH! by 3 :) # FINISH! by 1 :) # FINISH! by 4 :) # FINISH! by 2 :)
asyncio.sleep
ãã¤ãã£ãFutureãªãã¸ã§ã¯ãã0.2ç§å¾ã«å®äºããããã«ãã£ã¦ã³ã«ã¼ãã³ãåéãã¾ãããããnåç¶ãããã¨ãã³ã«ã¼ãã³ãçµãããã¨ã§Taskãªãã¸ã§ã¯ããå®äºãã¾ããã¡ãªã¿ã«ãåãç§æ°ã®call_later
ãè¤æ°ãã£ãå ´åããã®é åºã¯ããåããã¾ãããã®ã§ãã«ã¦ã³ã1以éã¯åºåã®é çªã¯ã°ãã°ãã«ãªã£ã¦ãã¾ãã
ã¨ããã§ããªãã ãè¦æ
£ããªãloop.run_until_complete(asyncio.wait(futures))
ã«ãã£ã¦ã«ã¼ããå®è¡ãã¦ãã¾ããã
asyncio.wait 㨠asyncio.gather
asyncio.wait(futures)
ã¯ã³ã«ã¼ãã³ã§ãããã©ã«ãã§ã¯ãå¼æ°ã®ä¸ã®Futureãªãã¸ã§ã¯ãããã¹ã¦å®äºãããå®äºããããããªã³ã«ã¼ãã³ã§ããã§ããããä»åã®å®è¡ã¯ãfuturesã®ä¸ã®ã³ã«ã¼ãã³ãå
¨é¨çµããã¾ã§ã«ã¼ããå®è¡ãç¶ãããã¨ããæ¡ä»¶ã«ãªã£ã¦ãã¾ããã¡ãªã¿ã«ãwait
ã¯ä»ã«ããã©ããï¼ã¤ã§ãå®äºããã°å®äºããä¾å¤ã誰ããåãããå®äºãã¨ãã風ãªæ¡ä»¶ãè¨å®ã§ãã¾ãã
ã¡ãªã¿ã«ãwait
ã«æ¸¡ãå¼æ°ã®ä¸ã®ã³ã«ã¼ãã³ã¯ãå
é¨ã§Taskãªãã¸ã§ã¯ãã«ããã¾ããã®ã§ã
n = get_input() loop = asyncio.get_event_loop() futures = set() for i in range(5): futures.add(boring_counting(i, n)) # tweak loop.run_until_complete(asyncio.wait(futures)) loop.close()
ã¨ãã¦ã大ä¸å¤«ã§ããã¨ã¯ãããå®å
¨ã®ãã ensure_future
ãã¦ããã¾ãããã
wait
ã¯è¿ãå¤ã¨ãã¦ãå®äºããFutureãªãã¸ã§ã¯ãã®éåãã¨ãæªå®ã®Futureãªãã¸ã§ã¯ãã®éåãã®ã¿ãã«ãè¿ãã¦ããã¾ãããã ããéåã§ãããã渡ããã·ã¼ã±ã³ã¹ã®é åºã¯ä¿ãããªãã¨æã£ãæ¹ãããã§ãããã
渡ããã·ã¼ã±ã³ã¹ã®é åºãä¿ã£ã¦ã»ããå ´åã¯asyncio.gather
ã®åºçªã§ãããã®é¢æ°ã¯å¯å¤åã®Futureãªãã¸ã§ã¯ããã¨ãããã®é çªãä¿ã£ãã¾ã¾ããã® çµæ ãè¿ãã¦ããã¾ããããå®å¿ãã¦ãã ããï¼ãã¡ããã³ã«ã¼ãã³ã渡ãã¦ããTaskãªãã¸ã§ã¯ãã«ãããã§ããã¾ããï¼çµæã欲ããå ´åã¯gather
ã®ã»ããããããããã¾ãããã
ãã£ãã®ã³ã¼ããå®è¡ãã¦æ°ã¥ãã¦ã»ããã®ã¯ãããã°ã©ã ãçµããã¾ã§ã« 0.2n ç§ç¨åº¦ããããã£ã¦ãªãã ããã¨ãããã¨ã§ãï¼ããããã®ã³ã«ã¼ãã³ã¯å段é㧠0.2ç§ã¹ãªã¼ãããã¯ãã§ãããã5*0.2n 㧠nç§ã¯ããããããªæ°ããã¾ãããã¡ãããããã¯ãªãããã¤ãã³ãã«ã¼ãã¯asyncio.sleep
ã®ã¨ããã§ããããã³ã°ãããã«ä»ã®ä»äºãé²ãããã¨ãã§ãã¾ããããã§ã 0.2nç§ããã£ã¦ãã¾ãã®ã¯ãåã« ä»ã«ãããã¨ããªããªã£ã¡ãã£ã ããå¾
ã£ã¦ãã ãã§ãããããã¤ãã³ãã«ã¼ãã®å¨ç¨ãã®çé«ã§ãï¼
ãã¦ãããä¸ã¤ä¾ãåºãã¦ã¿ã¾ããï¼
# coding=utf-8 import asyncio import sys from random import randint async def random_hit(n_upper, loop=None): if loop is None: loop = asyncio.get_event_loop() def _callback(future): print("DONE!") future = loop.create_future() future.add_done_callback(_callback) def _random_hit(n_upper, count): value = randint(1, n_upper) if value == n_upper: print("Hit!") future.set_result(count) else: print("Not yet.") count += 1 loop.call_soon(_random_hit, n_upper, count) loop.call_soon(_random_hit, n_upper, 1) return (await future) def get_input(): try: n = int(sys.argv[1]) except IndexError: print("Input an integer.") n = int(input()) if n < 1: n = 1 return n n = get_input() loop = asyncio.get_event_loop() result = loop.run_until_complete(random_hit(n)) print(result) # > python future3.py 10 # Not yet. # Not yet. # Not yet. # Not yet. # Not yet. # Not yet. # Not yet. # Not yet. # Not yet. # Hit! # DONE! # 10
ããã¯å°ãåã«ãã£ãrandom_hit
ã®ã³ã«ã¼ãã³çã§ããã³ã«ã¼ãã³ã®ä¸ã«é¢æ°å®ç¾©ãå
¥ãè¾¼ãã§å°ãè¤éã«ãªã£ã¦ãããããªæ°ããã¾ãããä½ããè¦ã¦æ¬²ããã®ã¯ãã«ã¼ãå®è¡ã®åæºåã®é¨åã§ãï¼
n = get_input() loop = asyncio.get_event_loop() result = loop.run_until_complete(random_hit(n))
ãã£ã3è¡ï¼ãã¡ãããnã®å¤ã®è¨å®ãé¢æ°åãããã¨ãããã¾ãããè¦ã¦ã»ããã®ã¯æç¶ã«ã¼ãã¨ãã®æ¹ã§ããã¤ãã³ãã«ã¼ããåå¾ããrandom_hit(n)
ã³ã«ã¼ãã³ãçµããã¾ã§ã«ã¼ããèµ°ãããããããããã¦ãã¾ããã
ä½ããå¤ãã£ãã®ã¯ãFutureãªãã¸ã§ã¯ããã³ã«ã¼ãã³å
é¨ã§ç¨æãã¦ããã¨ããã¨ããã§ããloop.run_until_complete
ãã³ã«ã¼ãã³ã®å¤ãè¿ãã¦ãããã®ã§ãFutureãªãã¸ã§ã¯ãããã£ã¡å´ãä¿æãã¦ããå¿
è¦ããªããªãã¾ããã確ãã«ãFutureãªãã¸ã§ã¯ããå
é¨ã§ç¨æããããã«ãå
é¨ã«é¢æ°å®ç¾©ãæããªããã°ãªããªãããã«ããªãã¾ããããã³ã«ã¼ãã³ä½¿ç¨è
å´ããããã°Futureãªãã¸ã§ã¯ãã®ä¸è©±ãããªãã¦ãããªãããã£ã¨ä½¿ãããããªãã¾ããã
èã
æãã¦ããã ããã¨ã¯æãã¾ãããasyncioã®å®éä¸ã®åºæ¬ã¦ãããã¯ã³ã«ã¼ãã³ã§ããwait
ãgather
ãloop.run_until_complete
ãè¦ãã¨ãããã«ã ãã³ã«ã¼ãã³ã使ãã ã¨è¨ã£ã¦ã¾ãããã
ã¨ããããã§ãããããã¯ç©æ¥µçã«ã³ã«ã¼ãã³ã使ã£ã¦ãããã¨ã«ãã¾ãããã
I/Oã«åãã£ã¦
asyncio.sleep
ã¯ããasyncioã¢ã¸ã¥ã¼ã«ã«ãããããããã³ã°ã®ä»£ããã¨ãã¦ç¨ãããã¾ãããå®æ
ã¯ãã ã®call_later
ã§ãããªãã¨ããããé¨ãããæ°åã«ãªãã¾ãããï¼ asyncioã¢ã¸ã¥ã¼ã«ã¯ããã®åãæ¬å½ãªãéåæI/Oã®ããã®ã¢ã¸ã¥ã¼ã«ãªã¯ãã§ãããã£ã±ãI/Oãå®éã«ã©ããã£ã¦éåæã«ãªãããã®ãã¨ããã®ãã¿ãªãã¨ããã®ã¢ã¸ã¥ã¼ã«ãç解ãããã¨ã«ã¯ãªããªãã§ãããã
Pythonã§æ±ããI/Oã¯ããããããããæ§ã ã«ããã¾ããæ¨æºI/Oã«ããã¡ã¤ã«I/Oã«ããããããä»ããå«ãªãããã«è¦ã¦ããããã»ã¹ééä¿¡ã§ããasyncioã¢ã¸ã¥ã¼ã«ãã¿ã¼ã²ããã¨ãã¦ããã®ã¯ã©ãããããã»ã¹ééä¿¡ã®ããã§ããããããã®ã¯ãã§ãããããasyncioã¢ã¸ã¥ã¼ã«ã®æãéããã·ã³ã°ã«ã¹ã¬ããã§ã®éåæãªå¦çå½¢æ ã¨ããã®ã¯ãã¬ã¤ãã³ã·ã®ããéä¿¡ãä¸åº¦ã«ãããããããã¨ãã«ä½¿ããã¯ã¶ã ããã§ããã¨ããããã§ã以ä¸ã§ã¯I/Oã®ä¸ã§ããããã»ã¹ééä¿¡ã«ã¤ãã¦è¦ã¦ããã¾ãï¼ã¡ãªã¿ã«ãæ¨æºI/Oããã¡ã¤ã«I/Oãã¡ãã£ã¨ç´°å·¥ããã¦ãããã°ãã¤ãã³ãã«ã¼ãã¯ããããã³ã°ããã«ä¸æãæ±ã£ã¦ãããããã«ãªãã¾ããããããã¼ãã¾ãããã®å ´åã¯ã¤ãã³ãã«ã¼ãããããã¨ããããã¯ããã«ãã¹ã¬ããããããã¨ãããã¨ã«ãªããã§ããã©ã詳ããã¯å¾ã§è©±ãã¾ãï¼ã
ã¾ãã¯æãããç¯ããï¼ã½ã±ãã
ä½æ°´æºãªéä¿¡æ¹æ³ã«ã¯ããã¤ãããã¾ãããããã§ã¯ã½ã±ããã ããåãä¸ãããã¨ã«ãã¾ãï¼ä»ã®ã«ã¤ãã¦ã¯ããã¥ã¡ã³ããè¦ã¦ãã ããï¼ã
- http://docs.python.jp/3/library/asyncio-eventloop.html#low-level-socket-operations
- http://docs.python.jp/3/library/asyncio-eventloop.html#watch-file-descriptors
ã¨ã¯ããããããããã½ã±ããã®ãã³ããããã³ã°ãªæ±ãæ¹ã¨ããã°ãæ¢ã«selectorãç¨ããæ¹æ³ãããã¾ãï¼ã¤ãã³ãã«ã¼ãããããå©ç¨ããªãæã¯ããã¾ããããå®éãããã¦ãã¾ãã
ã¤ãã³ãã«ã¼ãã¯èªåã®selectorãæã£ã¦ãããããªãé »ç¹ã«ããããã§ãã¯ï¼ãã¡ãããã³ããããã³ã°ã§ï¼ ãã¦ãã¾ã*2ãä½æ°´æºãªã½ã±ããã®æä½ã¯ããã®selectorã«ã½ã±ãããç»é²ããèªã¿æ¸ãå¯è½ã«ãªã次第ãç»é²æã«æ¸¡ãã¦ãããã³ã¼ã«ããã¯é¢æ°ã§å¦çããããã«ãã¾ãããã¡ãããã³ã¼ã«ããã¯ã¯ãã®ã½ã±ããã§ã®èªã¿æ¸ããå¯è½ã«ãªã次第ãã¤ãã³ãã«ã¼ãã«ä»äºã¨ãã¦è¿½å ããã¾ãï¼
ã½ã±ãããã«ã¼ãï¼ã®selectorï¼ã«ç»é²ããã«ã¯æ¬¡ã®ã¡ã½ãããç¨ãã¾ãï¼
loop.add_reader(fd, callback, *args)
loop.remove_reader(fd)
loop.add_writer(fd, callback, *args)
loop.remove_writer(fd)
fd ã¯ãã¡ã¤ã«ãã£ã¹ã¯ãªãã¿ã§ãããã½ã±ããããã®ã¾ã¾æ¸¡ãã¦ã大ä¸å¤«ã§ãã
èå¿ã®èªã¿æ¸ãã¯æ¬¡ã®ã¡ã½ããã§è¡ãã¾ãããã£ã¨ã³ã¼ã«ããã¯å ã§ä½¿ããã¨ã§ãããï¼
loop.sock_recv(sock, nbytes)
loop.sock_sendall(sock, data)
ã½ã±ãããããã¼ã¿ã欲ãããããªã³ã«ã¼ãã³ã¯ãFutureãªãã¸ã§ã¯ããä½ãããã®Futureãªãã¸ã§ã¯ããã³ã¼ã«ããã¯ã®å¼æ°ã¨ãã¦æ¸¡ãã¦ãããã³ã¼ã«ããã¯ã®ä¸ã§èªã¿åºãããã¼ã¿ãFutureãªãã¸ã§ã¯ãã«ã»ãããã¦ãããã°ããããã§ãããã¡ãããã³ã«ã¼ãã³ã¯ãã®Futureãªãã¸ã§ã¯ãã使ã£ã¦ await ãã¦ããã¾ãã
ã½ã±ããã®æ¥ç¶ã«é¢ãã¦ããã«ã¼ãã®selectorã«ç£è¦ãã¦ããããã¨ãã§ãã¾ãï¼
loop.sock_connect(sock, address)
ï¼add_writer
ã®ã³ã¼ã«ããã¯å ã§loop.sock_accept(sock)
ï¼add_reader
ã®ã³ã¼ã«ããã¯å ã§
ä½æ°´æºã½ã±ããã使ãããããã©ãã½ã±ããèªä½ã«ã¤ãã¦ãã¾ãç¥ããªãã¨ãã人ã¯ãHOWTOãã²ã¨ã¾ãèªããã¨ããããããã¾ãããããã®æ°ããªãã®ã§ããã°ãä½æ°´æºã«ããã¦ãã³ããããã³ã°I/Oãå¯è½ã ã¨ãããã¨ãç¥ã£ã¦ã»ããã£ãã ããªã®ã§ã以ä¸ã¯é£ã°ãã¦ããã£ã¦ãæ§ãã¾ããã
ç°¡åã«ã¯ãã¯ã©ã¤ã¢ã³ãã½ã±ããï¼IPv4, TCPï¼ã®å ´åã
- ã½ã±ãããä½ãï¼
sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
ï¼ - ãã³ããããã³ã°ã«ããï¼
sock.setblocking(False)
ï¼ - ã«ã¼ãã®selectorã«ç»é²ï¼
loop.add_writer(sock, callback, *args)
ï¼ - ã³ã¼ã«ããã¯é¢æ°ä¸ã§ãã½ã±ãããã¤ãªãï¼
loop.sock_connect(sock, address)
ï¼
ãããã ãã§ããµã¼ãã½ã±ããï¼IPv4, TCPï¼ã®å ´åã¯ã
- ã½ã±ãããä½ãï¼
sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
ï¼ - ãã³ããããã³ã°ã«ããï¼
sock.setblocking(False)
ï¼ - bindï¼
sock.bind(address, port)
ï¼ - listenï¼
sock.listen(backlog)
ï¼ - ã«ã¼ãã®selectorã«ç»é²ï¼
loop.add_reader(sock, callback, *args)
ï¼ - ã³ã¼ã«ããã¯é¢æ°ä¸ã§ãã½ã±ãããåãå
¥ãï¼
loop.sock_accept(sock)
ï¼
ã¨ããã°ããã§ãããã
è£è¶³ï¼ãã®ä»ã®ã½ã±ãã種
ä¸ã§ã¯IPv4ã¢ãã¬ã¹ãã¡ããªã¼ãç¨ããTCPã¿ã¤ãã®ã½ã±ãããä¾ã«æãã¾ããããIPv6ãBluetoothã¢ãã¬ã¹ãã¡ããªã¼ãç¨ããããUDPã¿ã¤ããçã¿ã¤ãã®ã½ã±ãããã¤ãããã¨ãã§ãã¾ãã
socketã¢ã¸ã¥ã¼ã«ã«ããAF_*
å®æ°ã¯ã¢ãã¬ã¹ãã¡ããªã¼ã表ããSOCK_*
å®æ°ã¯ã½ã±ããã¿ã¤ãã表ãã¾ãããã詳ããå
容ã¯ããã¥ã¡ã³ããã©ããã
ãã£ã¨é«æ°´æºãï¼ï¼ãã©ã³ã¹ãã¼ãï¼ãããã³ã«
ãã¹ã¦ã®ããã»ã¹ééä¿¡ã¯ã½ã±ããã«éããâ¦â¦ã¨ã¾ã§ã¯è¨ãã¾ãããã大æµã®ããã»ã¹ééä¿¡ã¯ç¢ºãã«ã½ã±ããã§ã§ãããã§ããããããããã¨ããã³ã¼ã«ããã¯ãæããã¦ã«ã¼ãã«é ãããã ããé常ã«ç°¡åãªæ¹æ³ã§éåæãªããã»ã¹ééä¿¡ãå®ç¾ã§ããããã§ãããæ¥ç¶ãèªã¿æ¸ããåæã¨ããä¸é£ã®å¦çãããããã®ã³ã¼ã«ããã¯é¢æ°ã«æ¸ããã¨ã«ãªãã®ã§ãããã½ã±ããã®ä¸çã追ãã®ã«ãç®ã ãè¡ã£ããæ¥ãããå°ãé¢åããããã§ããéä¿¡ã®ä¸é£ã®æµããè¦ã¯ã©ããªã³ã¼ã«ããã¯ãããããã®æ®µéã§å¼ã°ããã®ããã¨ããã®ã¯ä¸ç®æã«æ¸ãã¦ãã£ãã»ããä»ã®èª°ãã«ã¨ã£ã¦ãããã¦æªæ¥ã®ããªãã«ã¨ã£ã¦ã親åã§ãããã
ã¨ããããã§ãasyncioã¢ã¸ã¥ã¼ã«ã®ãã©ã³ã¹ãã¼ãï¼ãããã³ã«ã®åºçªã§ãããããã³ã«ã¯ãããéä¿¡ãªãã¸ã§ã¯ãï¼âã½ã±ããï¼ã®ä¸é£ã®æµãï¼æ¥ç¶ãèªã¿æ¸ããåæï¼ãã¡ã½ããã¨ãã¦è¨è¿°ããããã®ã¯ã©ã¹ã§ãã¾ãã«ä»ã®ç§ãã¡ãæ±ãã¦ãããã®ã§ãã
ç°¡åã«èª¬æããã¨ããããã³ã«ã¯æå®ã®ãã¼ã¿æ§å¼ãæ±ãããã®å¦çï¼æå®ã®ãã¼ã¿æ§å¼ã®ã¢ã¬ã³ã¬ï¼ãæ ãããã©ã³ã¹ãã¼ãã¯å®éã®I/Oããããã¡ãªã³ã°ï¼I/Oç¾å ´ã®ã¢ã¬ã³ã¬ï¼ãæ ãã¾ãããããã³ã«ãã¡ã¯ããªã¼ã¯åæ¥ç¶ãã¨ã«ãããã³ã«ã¤ã³ã¹ã¿ã³ã¹ãæ°ãã«ä½ã£ã¦æä¾ãã¦ããã¾ãã
ãã©ã³ã¹ãã¼ã
asyncioã¢ã¸ã¥ã¼ã«ã¯ç¾å¨ TCP, UDP, SSL, ãµãããã»ã¹ãã¤ãã®ãã©ã³ã¹ãã¼ããå®è£ ãã¦ãã¾ããéä¿¡ã«ããã¦å®éã«ç¸æã¨ããã¨ãããã®ããã©ã³ã¹ãã¼ãã®å½¹ç®ã§ããå種ãã©ã³ã¹ãã¼ãã¯ããããã®éä¿¡ã®å½¢æ ã«å¯¾å¿ãã¦ãããç¸å¿ã®ã¡ã½ãã群ãæã¡åããã¦ãã¾ãã
以ä¸ã«ãã©ã³ã¹ãã¼ããåæãã¾ãããå¾ã§è¦ãããã«ãasyncioã¢ã¸ã¥ã¼ã«ã«ã¯ãåºæ¬çãªãããã³ã«ãããããã®ãã©ã³ã¹ãã¼ããåãããããªãã®ã¨ãã¦ç¨æããã¦ããã®ã§ãåºæ¬çã«ã¯ãã©ã³ã¹ãã¼ããç´æ¥è§¦ããããªãã¨ã¯ãªããã¨æãã¾ãã
BaseTransport
ï¼åºåºãã©ã³ã¹ãã¼ãReadTransport
ï¼èªã¿è¾¼ã¿å°ç¨WriteTransport
ï¼æ¸ãè¾¼ã¿å°ç¨DatagramTransport
ï¼UDPã«å¯¾å¿BaseSubprocessTransport
ï¼ãµãããã»ã¹éä¿¡ã«å¯¾å¿
ãããã³ã«
asyncioã¢ã¸ã¥ã¼ã«ã«ã¯ããããªå¤§ããããªãããã³ã«ã¯ãªããããããç°ãªããã©ã³ã¹ãã¼ãããã¤ãããã³ã«ã¨ãã¦ãµãã¯ã©ã¹ãçºå±ãã¦ããã ãã§ãï¼ã¨ã¯ããããããã®ãããã§ãã©ã³ã¹ãã¼ããç´æ¥è§¦ããã«æ¸ã¿ã¾ããããååããããããã®ã§ãï¼ã
BaseProtocol
ï¼åºåºãããã³ã«Protocol
ï¼TCPãSSLãã©ã³ã¹ãã¼ããç¨ãããããã³ã«DatagramProtocol
ï¼UDPãã©ã³ã¹ãã¼ããç¨ãããããã³ã«SubprocessProtocol
ï¼ãµãããã»ã¹ãã©ã³ã¹ãã¼ããç¨ãããããã³ã«
å ·ä½çã«ã©ããã£ãæ§å¼ããã¼ã¿åä½ã¨ãã¦æ±ã£ã¦ãããã¨ãããã¨ã«ã¤ãã¦ã¯ãç¬èªã«ãããã³ã«ãçµãã§ãããã¨ã«ãªãã¾ããã¿ããªã«ã¨ã£ã¦å¿ è¦ãªãã®ã¯æãã誰ããä½ã£ã¦ãããã¨ã§ãããï¼ãµã¼ããã¼ãã£ã«æå¾ ãã¾ãããï¼ãã¨ãã°ãHTTPã«ã¤ãã¦ã¯ aiohttpã¢ã¸ã¥ã¼ã«ãããã¾ãï¼ã
ä¸çªãã使ãã§ããããProtocol
ã¯ã©ã¹ã«ã¤ãã¦è¦ã¦ããã¾ãããããã½ã±ããã®ä¸çãæ¸ãè¾¼ã¿ã¾ãããï¼
BaseProtocol.connection_made(transport)
ï¼ã³ãã¯ã·ã§ã³ä½ææã«å¼ã³åºãBaseProtocol.connection_lost(exc)
ï¼ã³ãã¯ã·ã§ã³ã失ããããéããããã¨ãã«å¼ã³åºãProtocol.data_received(data)
ï¼ãã¼ã¿ãåä¿¡ããã¨ãã«å¼ã°ãããProtocol.eof_received()
ï¼ç¸æãéä¿¡ãããã¼ã¿ããªããã¨ãä¼ãã¦ããã¨ãã«å¼ã°ããã
ãã®ä»ã®ãããã³ã«ã«ã¤ãã¦ã¯ããã¥ã¡ã³ããè¦ã¦ãã ããï¼ãããã³ã«ï¼ã
ã³ãã¯ã·ã§ã³ã®ä½æ
ã³ãã¯ã·ã§ã³ã¯ç¨ããã½ã±ããã¿ã¤ããã¢ãã¬ã¹ãã¡ããªã¼ã«ãã£ã¦ç°ãªãã¾ãããåºæ¬çã«ã¯ï¼
loop.create_connection()
ï¼SOCK_STREAM
ï¼TCPï¼ãç¨ããéä¿¡loop.create_datagram_endpoint()
ï¼SOCK_DGRAM
ï¼UDPï¼ãç¨ããéä¿¡
ã使ãã¾ããå¼æ°ã«ã¯è²ã ã¨æ¸¡ãã¾ãããåºæ¬çã«ã¯ ãããã³ã«ãã¡ããªã¼ï¼ãããã¯åã«ãç¡å¼æ°å¼ã³åºãã§ãããã³ã«ã¤ã³ã¹ã¿ã³ã¹ãè¿ããããªã³ã¼ã©ãã«ãªãã¸ã§ã¯ãï¼ããã¹ãã¢ãã¬ã¹ããã¼ãçªå· ãé ã«æ¸¡ãã¾ãã
ãã®ã¡ã½ããã¯ã³ã«ã¼ãã³é¢æ°ã§ããå¾ãããã³ã«ã¼ãã³ã¯æ¥ç¶ã試ããæ¥ç¶ãæåããã¨ããããã³ã«ã®connection_made
ã¡ã½ãããå¼ã°ããæçµçã«ï¼ãã©ã³ã¹ãã¼ã, ãããã³ã«ï¼ã®ã¿ãã«ãè¿ãã¾ãã
ä¸æ¹ãå¾ ã¡ããã³ãã¯ã·ã§ã³ï¼ãµã¼ãã¼ï¼ã«ã¯æ¬¡ã®ã¡ã½ããã使ãã¾ããå¼æ°ã¯ä¸ã®ã¡ã½ããã¨åãã§ãï¼
loop.create_server
ãã®ã¡ã½ããããæå¾ éããã³ã«ã¼ãã³é¢æ°ã§ããå¾ãããã³ã«ã¼ãã³ã¯æ¥ç¶ãæåããã¨ãµã¼ãã¼ãªãã¸ã§ã¯ããè¿ãã¾ãããµã¼ãã¼ãªãã¸ã§ã¯ãã«ã¯æ¬¡ã®ãã¨ãã§ãã¾ãï¼
server.close()
ï¼éåæã«ãå¾ æ©ä¸ã®ã½ã±ãããéãããµã¼ãã¼ãåæ¢ããserver.wait_closed()
ï¼close()
ãå®äºããã¾ã§å¾ æ©ããï¼ãã¡ããéåæã«ï¼ï¼sockets
ï¼ãµã¼ãã¼ãå¾ æ©ããã½ã±ããã®ãªã¹ã
ããã¥ã¡ã³ããæ°ã«ãªããªããããã«ç½®ãã¦ããã®ã§ãèªç±ã«ï¼
æµãã¨ãã¦ã¯ããããã³ã«ã渡ãã¦ã³ãã¯ã·ã§ã³ãã¤ããããã¨ã¯ãããã³ã«ã«æ¸ããéãã«ã½ã±ããã人çï¼ã½ã±ããçï¼ãéãã ãã§ããç°¡åãªããã¨ãï¼ãã¨ãã°ãechoï¼ãªãããããã³ã«ã®åºæ¬ã¡ã½ããã ãã§å®çµããã¨æãã¾ãã
ãã¼ã¿ã®éä¿¡
ãããã¼ã¿ã®éä¿¡ã«ã¤ãã¦è§¦ãã¦ãã¾ããã§ããï¼ãã¼ã¿ã®éä¿¡ã«ã¯ãã©ã³ã¹ãã¼ãã®ã¡ã½ãããç¨ãã¾ãï¼
ããã©ã³ã¹ãã¼ãã«ã¯è§¦ããªãã§ããã£ã¦è¨ã£ã¦ãã®ã«ï¼ãã£ã¦ï¼ ããã¯ç³ã訳ãªããã§ããç´æ¥ã¯è§¦ããªããã£ã¦è¨ã£ãããã«ãç§ãã¡ã¯ãããã³ã«æè¢ãã¤ããç¶æ
ã§ãããã©ã³ã¹ãã¼ãã触ããã¨ã¯ãªãã¯ãã§ãããããã³ã«ã®connection_made
ã¯ãã©ã³ã¹ãã¼ããå¼æ°ã¨ãã¦æ¸¡ããã¦å¼ã°ããã®ã§ããããã®ã½ã±ããã§ãã¼ã¿ãéããããªãã¨ããããªãããã®ã¨ãã«ãã©ã³ã¹ãã¼ãã«é¦è¼ªã§ãã¯ãã¦ããã¦ãã ããããã£ã¨ããããã³ã«ã¤ã³ã¹ã¿ã³ã¹ã®å±æ§ã«ã§ããã¦ããã¦ãã ããã£ã¦ãã¨ã§ãã
ãããã³ã«ãªãã¸ã§ã¯ãã«éä¿¡ç¨ã®ã¡ã½ãããå®ç¾©ãã¦ããã®ã¯ããæããããã¾ãããç¹ã«ã渡ããããã¼ã¿ã«ä½ãå°ç´°å·¥ãã¦ããç¸æã«éãã¤ãããããã®è·ç©ã«ãã©ãã°ãä»è¾¼ã¾ãã¦ãªããã確èªããããããå ´åã¯ããããã¹ãã§ãï¼ã§ããããã£ã¨è¯ãæ¹æ³ããã£ã¦ãããã¯ããå¾ã§åºä¼ããã¨ã«ãªãã¾ããããå°ãã ããå¾ ã¡ãï¼ï¼ã
ãããã³ã«ã®å ¸åçãªå®è£ ãªã©ã«ã¤ãã¦ã¯ãæ¨æºã¢ã¸ã¥ã¼ã«ã®ããããã³ã°ãªãããã³ã«ãåèã«ããã¨ããããããã¾ããï¼ã¤ã³ã¿ã¼ããããããã³ã«ï¼ã
ä¾
ããã¥ã¡ã³ãã®ä¾ãè¼ãã¾ãï¼
import asyncio class EchoClientProtocol(asyncio.Protocol): def __init__(self, message, loop): self.message = message self.loop = loop def connection_made(self, transport): transport.write(self.message.encode()) print('Data sent: {!r}'.format(self.message)) def data_received(self, data): print('Data received: {!r}'.format(data.decode())) def connection_lost(self, exc): print('The server closed the connection') print('Stop the event loop') self.loop.stop() loop = asyncio.get_event_loop() message = 'Hello World!' coro = loop.create_connection(lambda: EchoClientProtocol(message, loop), '127.0.0.1', 8888) loop.run_until_complete(coro) loop.run_forever() loop.close()
ããããããã½ã±ããã®æ°å¥ãªäººçã®è¨é²ã§ããæ¥ç¶æã«é½æ°ã« ‘Hello World!’ ã¨ç¸æã«éãã¤ããåãåã£ããã¼ã¿ãåã«åºåãã¾ãããªãã¦éå±ãªäººçãªãã â¦â¦ãæ¥ç¶ãåããã¨ãå½¼ã¯ã«ã¼ããæ¢ããããã¦ããã°ã©ã ãçµäºãã¾ãã
ã«ã¼ãã2åã«åãã¦åãã¦ãããã¨ã«æ³¨æãã¦ãã ãããããããã®ã¯ä»ã¾ã§ã«è¦ã¾ããã§ããããloop.run_until_complete
ã¯ã渡ãããFutureãªãã¸ã§ã¯ãã«ä¾å¤ãè¨å®ãããã¨ãã¯ãã®ä¾å¤ãããã¾ãã2åã«åãã¦å®è¡ãããã¨ã§ãä¸ãä¸æ¥ç¶ããã¾ãè¡ããªãã£ãã¨ãã«ã«ã¼ãããã®ã¾ã¾æ°¸é ã«èµ°ãç¶ããã¨ãããããªãã¨ãé²æ¢ã§ããããã§ããï¼
ç¶ãã¦ããµã¼ãã¼å´ãè¦ã¦ã¿ã¾ãããããã£ãã¨åãã§ãããã¥ã¡ã³ãã«ããä¾ãè¼ãã¾ãï¼
import asyncio class EchoServerClientProtocol(asyncio.Protocol): def connection_made(self, transport): peername = transport.get_extra_info('peername') print('Connection from {}'.format(peername)) self.transport = transport def data_received(self, data): message = data.decode() print('Data received: {!r}'.format(message)) print('Send: {!r}'.format(message)) self.transport.write(data) print('Close the client socket') self.transport.close() loop = asyncio.get_event_loop() # Each client connection will create a new protocol instance coro = loop.create_server(EchoServerClientProtocol, '127.0.0.1', 8888) server = loop.run_until_complete(coro) # Serve requests until Ctrl+C is pressed print('Serving on {}'.format(server.sockets[0].getsockname())) try: loop.run_forever() except KeyboardInterrupt: pass # Close the server server.close() loop.run_until_complete(server.wait_closed()) loop.close()
æ¬å½ã«åç´ãªã¨ã³ã¼ãµã¼ãã¼ã§ããæ¥ç¶ããã¨ãæ¥ç¶ããç¸æã®ååãããªã³ããã¾ããç¸æãããã¼ã¿ããããããããããªã³ããããã©ã³ã¹ãã¼ãã使ã£ã¦ãã®ã¾ã¾ç¸æã«éãè¿ãã¾ãï¼ã¨ã³ã¼ã ãããï¼ï¼ããã®ãã¨ããã©ã³ã¹ãã¼ããéãããã以ä¸ãã®ã³ãã¯ã·ã§ã³ã§ããåããããªãæ¨ãä¼ãã¾ãããã ãããµã¼ãã¼èªä½ãçµããããã§ã¯ãªããã¨ã«æ³¨æãã¦ãã ããï¼ãµã¼ãã¼èªä½ã¯ KeyboardInterrupt ããããã¾ã§ã¯åä½ãã¤ã¥ãã¾ããããæ°ãã«ã¯ã©ã¤ã¢ã³ããæ¥ç¶ãã¦ãããããã£ãã¨åããã¨ãç¹°ãè¿ãã¦ã¾ãæ¥ç¶ãåãã¾ãããªãã¦ææ³ã®æªãã³ã¼ã«ã»ã³ã¿ã¼ãªãã ï¼
Ctrl+C ã«ãã£ã¦ã«ã¼ããæ¢ã¾ãã°ããµã¼ãã¼ã«éããããå½ããã¡ããã¨éããã¾ã§ã«ã¼ããåãã¦ãããã«ã¼ããéãã¾ãããã§ãããã§ããã
â» ãï¼ãCtrl+C ãæ¼ãã¦ãåæ¢ããªããï¼ ããã¯å°ãã¾ããâ¦ããããã㦠Windowsã使ã£ã¦ã¾ãããï¼ Windowsã ã¨ãä½ãä»äºããã¦ããªãå¾ æ©ä¸ã®ã¤ãã³ãã«ã¼ãã«ã·ã°ãã«ãä¸æãä¼ãããªãããã§ããã¤ãã³ãã«ã¼ããä»äºããã¦ããéã« Ctrl+C ãæ¼ãã¨ä¸æãåå¿ãã¦ãããã®ã§ãå¿æ¥å¦ç½®ã¨ãã¦ã¯ã絶対ã«çµãããªãä»äºãä¸ãã¦ããæ¹æ³ãããã¾ããããã¾ã§å¿æ¥å¦ç½®ã¨ãã¦ãã§ããã©ã
ãã£ã¨ãã£ã¨é«æ°´æºãï¼ï¼ã¹ããªã¼ã
ãã©ã³ã¹ãã¼ãï¼ãããã³ã«ãç¨ãããã¨ã§ãåç´ã«ã½ã±ãããã¤ãã³ãã«ã¼ãã«æ¸¡ããããã¯æç¶è¦éãããããªãã¾ããï¼ ã½ã±ããã«ããä»ã®ããã»ã¹ã¨ã®ãã¼ã¿ã®ããåãã¯ããããããªãªã¯ãã§ããã§ãã確ãã«æ¬å½ã«I/Oã®ã¾ããã®è£ åã¯æ´ã£ã¦ãã¾ããããI/Oã¨ã³ããå´ã®ããã¨ãã®ãã¨ãå¿ãã¦ãã¾ããããã©ã³ã¹ãã¼ãï¼ãããã³ã«ã¯ç¢ºãã«ã½ã±ãããç¹ãã§ãããæãã«ç¸æãããã¼ã¿ãåãåã£ã¦ããã¾ããããã¯ãããã§ããããã®ãã¼ã¿ã¯ã©ããã£ããåãåãããã§ãããï¼ ç§ãã¡ããã®ãã¼ã¿ãåãåã£ãã®ã¯ããã®ãã¼ã¿ã使ã£ã¦ä½ããããã£ãããã«ã¡ããããã¾ããã
å ãã¦ããã©ã³ã¹ãã¼ãã¯ç¸ææ¹ã«ãã¤ããªãã¼ã¿ãéã£ã¦ããã¾ããããã©ã³ã¹ãã¼ãã«æ¸¡ãããã«ãæ¯åèªåã®æã§ï¼ããæ½è±¡çãªï¼ãã¼ã¿ããããã³ã«ãè¦å®ããæ§å¼ã®ãã¤ããªãã¼ã¿ã«å¤æããã®ãé¢åã§ãããã©ã³ã¹ãã¼ããéµä¾¿å±ããã ã¨ããããå°å ã®éãã寸æ³ã調ã¹ã¦ãããããå¿ è¦ãªåæãè²¼ã£ã¦ããããããéµä¾¿å±ã®åä»ä¿ãããããã¨ã¦ã楽ã ã¨æãã¾ãããï¼
ããã§ã¯ãç»å ´é¡ãã¾ãããï¼ ã¹ããªã¼ã ã¯ã¾ãã«é
éæ¥è
ã¨ç§ãã¡ãçµã¶çªå£ã®ãããªå½¹å²ãæããã¦ããã¾ããç§ãã¡ã¯StreamReader
çªå£ã§ãè·ç©ãã ãããã¨å¬ä¿ããStreamWriter
çªå£ã«è¡ã£ã¦ããã®è·ç©ããé¡ããã¾ããã¨ãé¡ãããã°ããã®ã§ãããã¡ãããåçªå£ã¯ç¹å®ã®é
éæ¥è
ã¨ææºãã¦ãã¦ãç§ãã¡ã®è·ç©ã«é©åãªå¦ç½®ãããä¸ã§ããã®æ¥è
ã«è·ç©ãæµãã¦ããã¾ãã
æãä½ã«è¨ãã°ããã©ã³ã¹ãã¼ãï¼ãããã³ã«ãããé«æ°´æºãªI/Oã·ã¹ãã ã§ãã
ãã©ã³ã¹ãã¼ãï¼ãããã³ã«ã¨ã¹ããªã¼ã ã®ä¾åé¢ä¿
ã¹ããªã¼ã ã¯ãã©ã³ã¹ãã¼ãï¼ãããã³ã«ã®ä¸ã«ãªããã¤ãã®ãªã®ã§ãããã«ã¯ä¾åé¢ä¿ãããã¾ããç°¡åã«ããã°ãåã ã®ãªãã¸ã§ã¯ããä½ãéã®å¼æ°ã«ä½ã渡ãã®ãã¨ããé¢ä¿ã§ããã¢ã¸ã¥ã¼ã«ã®æ§é ã®é¢ä¿ããè«çä¸ã®é層ï¼ã¹ããªã¼ã ããã©ã³ã¹ãã¼ãï¼ãããã³ã«ããä¸ã¨ããé層ï¼ã¨å°ãã ãå¤ãã£ã¦ãã¾ãï¼
StreamReader
ï¼ãæä¸å±¤ãã®ãªãã¸ã§ã¯ãã§ããStreamReaderProtocol
ï¼ã¹ããªã¼ã ç¨ã«ã«ã¹ã¿ã ããããããã³ã«ã§ãå¼æ°ã«StreamReader
ãåãã¾ããStreamWriter
ï¼ãæä¸å±¤ãã®ãªãã¸ã§ã¯ãã§ãããã©ã³ã¹ãã¼ãããããã³ã«ããªã¼ãã¼ã®ï¼ã¤ãå¼æ°ã«ã¨ãã¾ãã
åããã¨ã¯æãã¾ãããå¿ è¦ãªèªã¿æ¸ãã¹ããªã¼ã ãã¤ããéã«ã¯
StreamReader
ãªãã¸ã§ã¯ããæã«å ¥ãã- ããã使ã£ã¦
StreamReaderProtocol
ãªãã¸ã§ã¯ããæã«å ¥ãã - ãããï¼ï¼ãã©ã³ã¹ãã¼ãï¼ã使ã£ã¦
StreamWriter
ãæã«å ¥ãã
ã¨ããæµãã«ãªãã¾ããã¨ã¯ãããStreamReader
ã ããä½ã£ã¦ãç¹ã«ã§ãããã¨ã¯ä½ããªãããã¾ã¨ãã«ä½¿ãããã®ã§ããã°StreamReaderProtocol
ã¯å¿
é ã§ããåºæ¬çã«ãã¹ããªã¼ã ã使ãã¨ãã¯StreamWriter
ã¾ã§ä½ãã¯ããªã®ã§ããªãã§ããããã©ã³ã¹ãã¼ãï¼ãããã³ã«ã¯å¿
é ã§ãã
StreamReader 㨠StreamReaderProtocol
ã¾ãã¯ãåä¿¡çªå£ãããå§ãã¾ããããStreamReader
ã¯ãã®å
é¨ã«å庫ï¼ãããã¡ï¼bytearray
ï¼ï¼ããã£ã¦ãã¦ãStreamReaderProtocol
ã¯èªåãåãåã£ããã¼ã¿ãã©ãã©ãããã«æ¾ãè¾¼ãã§ããã¾ããç§ãã¡ã¯StreamReader
ã®ã¤ã³ã¿ã¼ãã§ã¼ã¹ãéãã¦å庫ã«ä¿ç®¡ãã¦ãããã¼ã¿ãåãåãã¾ãã
read()
ï¼å¼æ°ã«ãã¤ãæ°ã渡ãããããã©ã«ãã§ã¯EOFã¾ã§èªã¿è¾¼ãreadexactly()
ï¼å¼æ°ã«ãã¤ãæ°ã渡ãã¦ãå³å¯ã«ããã ãèªã¿è¾¼ãreadline()
ï¼æ¹è¡ãããã¾ã§èªã¿åããEOFãããå ´åã¯æ®ãããã¹ã¦èªã¿è¾¼ãreaduntil()
ï¼separator
å¼æ°ã«æ¸¡ãããã¤ãæååã¾ã§ãèªã¿è¾¼ã
ä½ãã大äºãªã®ã¯ãããããã³ã«ã¼ãã³ã ã¨ãããã¨ã§ãï¼ãããã®èªã¿åãã¡ã½ããã¯ãããã¡ã«ååãªãã¼ã¿ããã¾ãã¾ã§ãåã渡ãã await ãã¦ããã¾ãã
ç§ãã¡ã¨StreamReader
ãç¹ãã®ã¯ä¸ã§è¦ãread
ç³»ã®ã¡ã½ããã§ããé
éæ¥è
å´ãã¤ã¾ããã©ã³ã¹ãã¼ãï¼ãããã³ã«ã¨ã¯feed
ç³»ã®ã¡ã½ããã§è·ç©ãåãä»ãã¾ãï¼
feed_data()
feed_eof()
ãããã®ã¡ã½ãããç§ãã¡ãç´æ¥è§¦ããã¨ã¯ãªãã§ããããStreamReaderProtocol
ãStreamWriter
ãå
é¨ã§ãããã®ã¡ã½ãããè¯ããªã«ä½¿ã£ã¦ããã®ã§ããããã®ãµãã¯ã©ã¹ã¨ãã¦å®è£
ããã°ããã ãã§ãã
StreamReaderProtocol
ã¯ã¤ã³ã¹ã¿ã³ã¹ãã¤ããéã«ã第äºå¼æ°ã¨ãã¦client_connected_cb
ã«ã³ã¼ã«ããã¯ï¼é¢æ°ã§ãã³ã«ã¼ãã³ã§ãï¼ã渡ããã¨ãã§ãã¾ãããã®ã³ã¼ã«ããã¯ã¯ãæ¥ç¶ããã¨ãã«å¼ã°ãããã®ã§ãconnection_made
ã¡ã½ããã¨ä¼¼ãå½¹å²ããã¡ã¾ãã
StreamWriter
StreamWriter
ã¯ã»ã¨ãã©ãã©ã³ã¹ãã¼ãã®ã©ããã§ãï¼write(data)
ãwritelines(list_of_data)
ãwrite_eof()
ã¡ã½ãããã¤ã³ã¿ã¼ãã§ã¼ã¹ã¨ãã¦ãã£ã¦ãããååã®ãã©ã³ã¹ãã¼ãã®ã¡ã½ãããå¼ã³åºãã¾ãã
ã³ãã¯ã·ã§ã³
ããã©ã«ãï¼TCPï¼ã®StreamReader
, StreamWriter
, StreamReaderProtocol
ã§ååãªå ´åã¯ãopen_connection
ã使ãã¾ããããã¯create_connection
ã®ã©ããã¼ã§ããå®éã®ã½ã¼ã¹ã³ã¼ãï¼ãè¥å¹²æ¹å¤ãããã®ï¼ãè¦ã¦ã¿ã¾ãï¼
async def open_connection(host=None, port=None, *, loop=None, limit=_DEFAULT_LIMIT, **kwds): if loop is None: loop = events.get_event_loop() reader = StreamReader(limit=limit, loop=loop) protocol = StreamReaderProtocol(reader, loop=loop) transport, _ = await loop.create_connection( lambda: protocol, host, port, **kwds) writer = StreamWriter(transport, protocol, reader, loop) return reader, writer
æ¡ã®å®ãã¾ããªã¼ãã¼ãæã«å
¥ããããã使ã£ã¦ãããã³ã«ãæã«å
¥ãã¾ãããããããcreate_connection
ãã¦ããã©ã³ã¹ãã¼ããæã«å
¥ãã¾ããæå¾ã«ããã®ï¼ã¤ããã¹ã¦ä½¿ã£ã¦ãã©ã¤ã¿ã¼ãæã«å
¥ãããªã¼ãã¼ã¨ã©ã¤ã¿ã¼ãè¿ãã¾ããç°¡åã§ããï¼
åæ§ã«ãcreate_server
ã®ã©ããçåå¨ã¨ãã¦start_server
ãããã¾ãï¼
async def start_server(client_connected_cb, host=None, port=None, *, loop=None, limit=_DEFAULT_LIMIT, **kwds): if loop is None: loop = events.get_event_loop() def factory(): reader = StreamReader(limit=limit, loop=loop) protocol = StreamReaderProtocol(reader, client_connected_cb, loop=loop) return protocol return (await loop.create_server(factory, host, port, **kwds))
ã¾ãããã£ã¦ããã¨ã¯å¤§ãããã¨ãªãã§ãããã
ããã§ã ãããçµãã
asyncioã¢ã¸ã¥ã¼ã«ã®æ ¹å¹¹ã§ããã¤ãã³ãã«ã¼ãããã¯ãã¾ããFutureãªãã¸ã§ã¯ããã³ã«ã¼ãã³ããã©ã³ã¹ãã¼ãï¼ãããã³ã«ãã¹ããªã¼ã ã¨ã¿ã¦ãã¾ãããasyncioã¢ã¸ã¥ã¼ã«ã®å¤§ä½ã®è¦ç´ ã¯è¦ã¦ããã®ã§ãã¢ã¸ã¥ã¼ã«ã®ããã¥ã¡ã³ãã®å¤§åã¯è¦ããã¨ãããã®ã«ãªã£ã¦ããã¨æãã¾ãã
ãµãããã»ã¹ã ãã¯ãã£ã¦ãªãã§ãããããã¾ã§ç解ãã¦ããã°ãããªå¤§ãããã¨ãªãã§ãããï¼æ¶æ¸¬ï¼ãããã§ã¯ã¬ããã¨ã³ã¸ã§ã¤ asyncioï¼
ãã£ãrun_in_executor
æ¸ãã¦ãªãã»ã»ã»ã»ã»ã»