Äú¿ÉÒÔ¾èÖú£¬Ö§³ÖÎÒÃǵĹ«ÒæÊÂÒµ¡£

1Ôª 10Ôª 50Ôª





ÈÏÖ¤Â룺  ÑéÖ¤Âë,¿´²»Çå³þ?Çëµã»÷Ë¢ÐÂÑéÖ¤Âë ±ØÌî



  ÇóÖª ÎÄÕ ÎÄ¿â Lib ÊÓÆµ iPerson ¿Î³Ì ÈÏÖ¤ ×Éѯ ¹¤¾ß ½²×ù Model Center   Code  
»áÔ±   
   
 
     
   
 ¶©ÔÄ
  ¾èÖú
̸̸PythonЭ³Ì¼¼ÊõµÄÑݽø
 
À´Ô´£º51CTO ·¢²¼ÓÚ:2017-9-29
  4099  次浏览      28
 

Ò»¡¢ÒýÑÔ

1. ´æ´¢Æ÷ɽ

´æ´¢Æ÷ɽÊÇ Randal Bryant ÔÚ¡¶ÉîÈëÀí½â¼ÆËã»úϵͳ¡·Ò»ÊéÖÐÌá³öµÄ¸ÅÄî¡£

»ùÓڳɱ¾¡¢Ð§ÂʵĿ¼Á¿£¬¼ÆËã»ú´æ´¢Æ÷±»Éè¼Æ³É¶à¼¶½ð×ÖËþ½á¹¹£¬Ëþ¶¥ÊÇËÙ¶È×î¿ì¡¢³É±¾×î¸ßµÄ CPU ÄÚ²¿µÄ¼Ä´æÆ÷(Ò»°ã¼¸ KB)Óë¸ßËÙ»º´æ£¬Ëþµ×Êdzɱ¾×îµÍ¡¢ËÙ¶È×îÂýµÄ¹ãÓòÍøÔÆ´æ´¢(Èç°Ù¶ÈÔÆÃâ·Ñ 2T )

´æ´¢Æ÷ɽµÄÖ¸µ¼ÒâÒåÔÚÓÚ½ÒʾÁËÁ¼ºÃÉè¼Æ³ÌÐòµÄ±ØÒªÌõ¼þÊÇÐèÒªÓÐÓÅÐãµÄ¾Ö²¿ÐÔ£º

ʱ¼ä¾Ö²¿ÐÔ£ºÏàͬʱ¼äÄÚ£¬·ÃÎÊͬһµØÖ·´ÎÊýÔ½¶à£¬Ôòʱ¼ä¾Ö²¿ÐÔ±íÏÖÔ½¼Ñ;

¿Õ¼ä¾Ö²¿ÐÔ£ºÏÂÒ»´Î·ÃÎʵĴ洢Æ÷µØÖ·ÓëÉÏÒ»´ÎµÄ·ÃÎʹýµÄ´æ´¢Æ÷µØÖ·Î»ÖÃÁÚ½ü;

2. cpuµÄʱ¼ä¹Û

ÎÒÃǽ«Ò»¸öÆÕͨµÄ 2.6GHz µÄ CPU µÄÑÓ³Ùʱ¼ä·Å´óµ½ÈËÄÜÌåÑéµÄ³ß¶ÈÉÏ(Êý¾ÝÀ´×Ô΢ÐŹ«ÖںоÔ˵ÂëÊÂ)£ºÔÚ´æ´¢Æ÷¶¥²ãÖ´Ðе¥Ìõ¼Ä´æÆ÷Ö¸ÁîµÄʱ¼äΪ1ÃëÖÓ;´ÓµÚÎå²ã´ÅÅ̶Á 1MB Êý¾ÝÈ´ÐèÒªÒ»Äê°ë;ping ²»Í¬µÄ³ÇÓòÍøÖ÷»ú£¬ÍøÂç°üÐèÒª×ß 12.5 Äê¡£

Èç¹û³ÌÐò·¢ËÍÁËÒ»¸ö HTTP °üºó±ã×èÈûÔÚͬ²½µÈ´ýÏìÓ¦µÄ¹ý³ÌÉÏ£¬¼ÆËã»ú²»µÃ²»ÉµµÈ 12 ÄêºóµÄÄǸöÏìÓ¦ÔÙ´¦Àí±ðµÄÊÂÇ飬µÍϵÄÓ²¼þÀûÓÃÂʱØÈ»µ¼ÖµÍϵijÌÐòЧÂÊ¡£

3. ͬ²½±à³Ì

´ÓÒÔÉÏÊý¾Ý¿ÉÒÔ¿´³ö£¬ÄÚ´æÊý¾Ý¶Áд¡¢´ÅÅÌѰµÀ¶Áд¡¢Íø¿¨¶ÁдµÈ²Ù×÷¶¼ÊÇ I/O ²Ù×÷£¬Í¬²½³ÌÐòµÄÆ¿¾±ÔÚÓÚÂþ³¤µÄ I/O µÈ´ý£¬ÏëÒªÌá¸ß³ÌÐòЧÂʱØÐë¼õÉÙ I/O µÈ´ýʱ¼ä£¬´ÓÌá¸ß³ÌÐòµÄ¾Ö²¿ÐÔ×ÅÊÖ¡£

ͬ²½±à³ÌµÄ¸Ä½ø·½Ê½ÓÐ¶à½ø³Ì¡¢¶àỊ̈߳¬µ«¶ÔÓÚ c10k ÎÊÌâ¶¼²»ÊÇÁ¼ºÃµÄ½â¾ö·½°¸£¬¶à½ø³ÌµÄ·½Ê½´æÔÚ²Ù×÷ϵͳ¿Éµ÷¶È½ø³ÌÊýÁ¿ÉÏÏ޽ϵͣ¬½ø³Ì¼äÉÏÏÂÎÄÇл»Ê±¼ä¹ý³¤£¬½ø³Ì¼äͨÐŽÏΪ¸´ÔÓ¡£

¶ø Python µÄ¶àÏ̷߳½Ê½£¬ÓÉÓÚ´æÔÚÖÚËùÖÜÖªµÄ GIL Ëø£¬ÐÔÄÜÌáÉý²¢²»Îȶ¨£¬½öÄÜÂú×ã³É°ÙÉÏǧ¹æÄ£µÄ I/O Ãܼ¯ÐÍÈÎÎñ£¬¶àÏ̻߳¹ÓÐÒ»¸öȱµãÊÇÓɲÙ×÷ϵͳ½øÐÐÇÀռʽµ÷¶È´æÔÚ¾ºÌ¬Ìõ¼þ£¬¿ÉÄÜÐèÒªÒýÈëÁËËøÓë¶ÓÁеȱ£ÕÏÔ­×ÓÐÔ²Ù×÷µÄ¹¤¾ß¡£

4. Òì²½±à³Ì

˵µ½Òì²½·Ç×èÈûµ÷Óã¬Ä¿Ç°µÄ´úÃû´Ê¶¼ÊÇ epoll Óë kqueue£¬select/poll ÓÉÓÚЧÂÊÎÊÌâ»ù±¾Òѱ»È¡´ú¡£

epoll ÊÇ04Äê Linux2.6 ÒýÈëÄں˵ÄÒ»ÖÖ I/O ʼþ֪ͨ»úÖÆ£¬ËüµÄ×÷ÓÃÊǽ«´óÁ¿µÄÎļþÃèÊö·ûÍйܸøÄںˣ¬Äں˽«×îµ×²ãµÄ I/O ״̬±ä»¯·â×°³É¶Áдʼþ£¬ÕâÑù¾Í±ÜÃâÁËÓɳÌÐòԱȥÖ÷¶¯ÂÖѯ״̬±ä»¯µÄÖØ¸´¹¤×÷£¬³ÌÐòÔ±½«»Øµ÷º¯Êý×¢²áµ½ epoll µÄ״̬ÉÏ£¬µ±¼ì²âµ½Ïà¶ÔÓ¦ÎļþÃèÊö·û²úÉú״̬±ä»¯Ê±£¬¾Í½øÐк¯Êý»Øµ÷¡£

ʼþÑ­»·ÊÇÒì²½±à³ÌµÄµ×²ã»ùʯ¡£

ÉÏͼÊǼòµ¥µÄEventLoopµÄʵÏÖÔ­Àí£¬

1.Óû§´´½¨ÁËÁ½¸ösocketÁ¬½Ó£¬½«ÏµÍ³·µ»ØµÄÁ½¸öÎļþÃèÊö·ûfd3¡¢fd4ͨ¹ýϵͳµ÷ÓÃÔÚepollÉÏ×¢²á¶Áдʼþ;

2.µ±Íø¿¨½âÎöµ½Ò»¸ötcp°üʱ£¬Äں˸ù¾ÝÎåÔª×éÕÒµ½ÏàÓ¦µ½ÎļþÃèÊö·û£¬×Ô¶¯´¥·¢Æä¶ÔÓ¦µÄ¾ÍÐ÷ʼþ״̬£¬²¢½«¸ÃÎļþÃèÊö·ûÌí¼Óµ½¾ÍÐ÷Á´±íÖС£

3.³ÌÐòµ÷ÓÃepoll.poll()£¬·µ»Ø¿É¶ÁдµÄʼþ¼¯ºÏ¡£

4.¶Ôʼþ¼¯ºÏ½øÐÐÂÖѯ£¬µ÷Óûص÷º¯ÊýµÈ

5.Ò»ÂÖʼþÑ­»·½áÊø£¬Ñ­»·Íù¸´¡£

epoll ²¢·ÇÒøµ¯£¬´ÓͼÖпÉÒԹ۲쵽£¬Èç¹ûÓû§¹Ø×¢µÄ²ã´ÎºÜµÍ£¬Ö±½Ó²Ù×÷epollÈ¥¹¹Ôìά»¤Ê¼þµÄÑ­»·£¬´Óµ×²ãµ½¸ß²ãµÄÒµÎñÂß¼­ÐèÒª²ã²ã»Øµ÷£¬Ôì³Écallback hell£¬²¢ÇҿɶÁÐԽϲËùÒÔ£¬Õâ¸ö·±ËöµÄ×¢²á»Øµ÷Óë»Øµ÷µÄ¹ý³ÌµÃÒÔ·â×°£¬²¢³éÏó³ÉEventLoop¡£EventLoopÆÁ±ÎÁ˽øÐÐepollϵͳµ÷ÓõľßÌå²Ù×÷¡£¶ÔÓÚÓû§À´Ëµ£¬½«²»Í¬µÄI/O״̬¿¼Á¿ÎªÊ¼þµÄ´¥·¢£¬Ö»Ðè¹Ø×¢¸ü¸ß²ã´Îϲ»Í¬Ê¼þµÄ»Øµ÷ÐÐΪ¡£ÖîÈçlibev, libeventÖ®ÀàµÄʹÓÃC±àдµÄ¸ßÐÔÄÜÒ첽ʼþ¿âÒѾ­È¡´úÕⲿ·ÖËöËéµÄ¹¤×÷¡£

ÔÚPython¿ò¼ÜÀïÒ»°ã»á¼ûµ½µÄÕ⼸ÖÖʼþÑ­»·£º

1.libevent/libev: Gevent(greenlet+ǰÆÚlibevent£¬ºóÆÚlibev)ʹÓõÄÍøÂç¿â£¬¹ã·ºÓ¦ÓÃ;

2.tornado: tornado¿ò¼Ü×Ô¼ºÊµÏÖµÄIOLOOP;

3.picoev: meinheld(greenlet+picoev)ʹÓõÄÍøÂç¿â£¬Ð¡ÇÉÇáÁ¿£¬Ïà½ÏÓÚlibeventÔÚÊý¾Ý½á¹¹ºÍʼþ¼ì²âÄ£ÐÍÉÏ×öÁ˸Ľø£¬ËùÒÔËٶȸü¿ì¡£µ«´Ógithub¿´ÆðÀ´ÒѾ­Äê¾ÃʧÐÞ£¬ÓõÄÈ˲»¶à¡£

4.uvloop: Python3ʱ´úµÄÐÂÆðÖ®Ðã¡£Guido²Ùµ¶´òÔìÁËasyncio¿â£¬asyncio¿ÉÒÔÅäÖÿɲå°ÎµÄevent loop£¬µ«ÐèÒªÂú×ãÏà¹ØµÄAPIÒªÇó£¬uvloop¼Ì³Ð×Ôlibuv£¬½«Ò»Ð©µÍ²ãµÄ½á¹¹ÌåºÍº¯ÊýÓÃPython¶ÔÏó°ü×°¡£Ä¿Ç°Sanic¿ò¼Ü»ùÓÚÕâ¸ö¿â

5. Э³Ì

EventLoop¼ò»¯Á˲»Í¬Æ½Ì¨ÉϵÄʼþ´¦Àí£¬µ«ÊÇ´¦Àíʼþ´¥·¢Ê±µÄ»Øµ÷ÒÀÈ»ºÜÂé·³£¬ÏìӦʽµÄÒì²½³ÌÐò±àд¶Ô³ÌÐòÔ±µÄÐÄÖÇÊÇÒ»ÏСµÄÂé·³¡£

Òò´Ë£¬Ð­³Ì±»ÒýÈëÀ´Ìæ´ú»Øµ÷ÒÔ¼ò»¯ÎÊÌ⡣Э³ÌÄ£ÐÍÖ÷ÒªÔÚÔÚÒÔÏ·½ÃæÓÅÓڻص÷Ä£ÐÍ£º

ÒÔ½üËÆÍ¬²½´úÂëµÄ±à³Ìģʽȡ´úÒì²½»Øµ÷ģʽ£¬ÕæÊµµÄÒµÎñÂß¼­ÍùÍùÊÇͬ²½ÏßÐÔÍÆÑݵģ¬Òò´Ë£¬ÕâÖÖͬ²½Ê½µÄ´úÂëдÆðÀ´¸ü¼ÓÈÝÒס£µ×²ãµÄ»Øµ÷ÒÀÈ»ÊÇcallback hell£¬µ«Õⲿ·ÖÔà»îÀÛ»îÒѾ­×ª½»¸ø±àÒëÆ÷Óë½âÊÍÆ÷È¥Íê³É£¬³ÌÐòÔ±²»Ò׳ö´í¡£

Òì³£´¦Àí¸ü¼Ó½¡È«£¬¿ÉÒÔ¸´ÓÃÓïÑÔÄڵĴíÎó´¦Àí»úÖÆ£¬»Øµ÷·½Ê½¡£¶ø´«Í³Òì²½»Øµ÷ģʽÐèÒª×Ô¼ºÅж¨³É¹¦Ê§°Ü£¬´íÎó´¦ÀíÐÐΪ¸´ÔÓ»¯¡£

ÉÏÏÂÎĹÜÀí¼òµ¥»¯£¬»Øµ÷·½Ê½´úÂëÉÏÏÂÎĹÜÀíÑÏÖØÒÀÀµ±Õ°ü£¬²»Í¬µÄ»Øµ÷º¯ÊýÖ®¼äÏ໥ñîºÏ£¬¸îÁÑÁËÏàͬµÄÉÏÏÂÎÄ´¦ÀíÂß¼­¡£Ð­³ÌÖ±½ÓÀûÓôúÂëµÄÖ´ÐÐλÖÃÀ´±íʾ״̬£¬¶ø»Øµ÷ÔòÊÇά»¤ÁËÒ»¶ÑÊý¾Ý½á¹¹À´´¦Àí״̬¡£

·½±ã´¦Àí²¢·¢ÐÐΪ£¬Ð­³ÌµÄ¿ªÏú³É±¾ºÜµÍ£¬Ã¿Ò»¸öЭ³Ì½öÓÐÒ»¸öÇáÇɵÄÓû§Ì¬Õ»¿Õ¼ä¡£

6. EventLoopÓëЭ³ÌµÄ·¢Õ¹Ê·

04Ä꣬event-driven µÄ nginx µ®Éú²¢¿ìËÙ´«²¥£¬06ÄêÒÔºó´Ó¶íÓïÇø¹ú¼ÒÀ©É¢µ½È«Çò¡£Í¬Ê±ÆÚ£¬EventLoop ±äµÃ¾ßÏó»¯Óë¶àÔª»¯£¬Ïà¼ÌÔÚ²»Í¬µÄ±à³ÌÓïÑÔʵÏÖ¡£

½üÊ®ÄêÒÔÀ´£¬ºó¶ËÁìÓòÄÚ¹ÅÀϵÄ×ÓÀý³ÌÓëʼþÑ­»·µÃµ½½áºÏ£¬Ð­³Ì(Э×÷ʽ×ÓÀý³Ì)¿ìËÙ·¢Õ¹£¬²¢Ò²¸ïÐÂÓëµ®ÉúÁËһЩÓïÑÔ£¬±ÈÈç golang µÄ goroutine£¬luajit µÄ coroutine£¬Python µÄ gevent,erlang µÄ process£¬scala µÄ actor µÈ¡£

¾Í²»Í¬ÓïÑÔÖÐÃæÏò²¢·¢Éè¼ÆµÄЭ³ÌʵÏÖ¶øÑÔ£¬Scala Óë Erlang µÄ Actor Ä£ÐÍ¡¢Golang ÖÐµÄ goroutine ¶¼½Ï Python ¸üΪ³ÉÊ죬²»Í¬µÄЭ³ÌʹÓÃͨÐÅÀ´¹²ÏíÄڴ棬ÓÅ»¯Á˾ºÌ¬¡¢³åÍ»¡¢²»Ò»ÖÂÐÔµÈÎÊÌ⡣Ȼ¶ø£¬¸ù±¾µÄÀíÄîûÓÐÇø±ð£¬¶¼ÊÇÔÚÓû§Ì¬Í¨¹ýʼþÑ­»·Çý¶¯ÊµÏÖµ÷¶È¡£

ÓÉÓÚÀúÊ·°ü¸¤½ÏÉÙ£¬ºó¶ËÓïÑÔÉϵĸ÷ÖÖÒì²½¼¼Êõ³ý Python Twisted Íâ»ù±¾Ò²Ã»ÓÐ callback hell µÄ´æÔÚ¡£ÆäËûµÄ·½°¸¶¼ÒѾ­½« callback hell µÄ¹ý³Ì½øÐзâ×°£¬½»¸ø¿â´úÂë¡¢±àÒëÆ÷¡¢½âÊÍÆ÷È¥½â¾ö¡£

ÓÐÁËЭ³Ì£¬ÓÐÁËʼþÑ­»·¿â£¬´«Í³µÄ C10K ÎÊÌâÒѾ­²»ÊÇÌôÕ½²¢ÒѾ­ÉÏÉýµ½ÁË C1M ÎÊÌâ¡£

¶þ¡¢Gevent

 

Python2 ʱ´úµÄЭ³Ì¼¼ÊõÖ÷ÒªÊÇ Gevent£¬ÁíÒ»¸ö meinheld ±È½ÏСÖÚ¡£Gevent ÓаýÓбᣬ¸ºÃæ¹ÛµãÈÏΪËüµÄʵÏÖ²»¹» Pythonic£¬ÍÑÀë½âÊÍÆ÷¶À×ÔʵÏÖÁ˺ںеĵ÷¶ÈÆ÷£¬monkey patch Èò»Á˽âµÄÓû§²úÉú»ìÏý¡£ÕýÃæ¹ÛµãÈÏΪÕýÊÇÕâÑù²ÅµÃÒÔÆÁ±ÎËùÓеÄϸ½Ú£¬¼ò»¯Ê¹ÓÃÄѶȡ£

Gevent »ùÓÚ Greenlet Óë Libev£¬greenlet ÊÇÒ»ÖÖ΢Ï̻߳òÕßЭ³Ì£¬ÔÚµ÷¶ÈÁ£¶ÈÉÏ±È PY3 µÄЭ³Ì¸ü´ó¡£greenlet ´æÔÚÓÚÏß³ÌÈÝÆ÷ÖУ¬ÆäÐÐΪÀàËÆỊ̈߳¬ÓÐ×Ô¼º¶ÀÁ¢µÄÕ»¿Õ¼ä£¬²»Í¬µÄ greenlet µÄÇл»ÀàËÆ²Ù×÷ϵͳ²ãµÄÏß³ÌÇл»¡£

greenlet.hub Ò²ÊÇÒ»¸ö¼Ì³ÐÓÚÔ­Éú greenlet µÄ¶ÔÏó£¬Ò²ÊÇÆäËû greenlet µÄ¸¸½Úµã£¬ËüÖ÷Òª¸ºÔðÈÎÎñµ÷¶È¡£µ±Ò»¸ö greenlet Э³ÌÖ´ÐÐÍ겿·ÖÀý³Ìºóµ½´ï¶Ïµã£¬Í¨¹ý greenlet.switch() ÏòÉÏת½»¿ØÖÆÈ¨¸ø hub ¶ÔÏó£¬hub Ö´ÐÐÉÏÏÂÎÄÇл»µÄ²Ù×÷£º´Ó¼Ä´æÆ÷¡¢¸ßËÙ»º´æÖб¸·Ýµ±Ç° greenlet µÄÕ»ÄÚÈݵ½ÄÚ´æÖУ¬²¢½«Ô­À´±¸·ÝµÄÁíÒ»¸ö greenlet Õ»Êý¾Ý»Ö¸´µ½¼Ä´æÆ÷ÖС£

hub ¶ÔÏóÄÚ·â×°ÁËÒ»¸ö loop ¶ÔÏó£¬loop ¸ºÔð·â×° libev µÄÏà¹Ø²Ù×÷²¢ÏòÉÏÌṩ½Ó¿Ú£¬ËùÓÐ greenlet ÔÚͨ¹ý loop Çý¶¯µÄ hub ϱ»µ÷¶È¡£

Èý¡¢´Óyieldµ½async/await

1. Éú³ÉÆ÷µÄ½ø»¯

ÔÚ Python2.2 ÖУ¬µÚÒ»´ÎÒýÈëÁËÉú³ÉÆ÷£¬Éú³ÉÆ÷ʵÏÖÁËÒ»ÖÖ¶èÐÔ¡¢¶à´ÎȡֵµÄ·½·¨£¬´Ëʱ»¹ÊÇͨ¹ý next ¹¹ÔìÉú³Éµü´úÁ´»ò next ½øÐжà´Îȡֵ¡£

Ö±µ½ÔÚ Python2.5 ÖУ¬yield ¹Ø¼ü×Ö±»¼ÓÈëµ½Óï·¨ÖУ¬Õâʱ£¬Éú³ÉÆ÷ÓÐÁ˼ÇÒ书ÄÜ£¬ÏÂÒ»´Î´ÓÉú³ÉÆ÷ÖÐȡֵ¿ÉÒÔ»Ö¸´µ½Éú³ÉÆ÷ÉÏ´Î yield Ö´ÐеÄλÖá£

֮ǰµÄÉú³ÉÆ÷¶¼ÊǹØÓÚÈçºÎ¹¹Ôìµü´úÆ÷£¬ÔÚ Python2.5 ÖÐÉú³ÉÆ÷»¹¼ÓÈëÁË send ·½·¨£¬Óë yield ´îÅäʹÓá£

ÎÒÃÇ·¢ÏÖ£¬´Ëʱ£¬Éú³ÉÆ÷²»½ö½ö¿ÉÒÔ yield ÔÝÍ£µ½Ò»¸ö״̬£¬»¹¿ÉÒÔÍùËüÍ£Ö¹µÄλÖÃͨ¹ý send ·½·¨´«ÈëÒ»¸öÖµ¸Ä±äÆä״̬¡£

¾ÙÒ»¸ö¼òµ¥µÄʾÀý£¬Ö÷ÒªÊìϤ yield Óë send ÓëÍâ½çµÄ½»»¥Á÷³Ì£º

def jump_range(up_to):
step = 0
while step < up_to:
jump = yield step
print("jump", jump)
if jump is None:
jump = 1
step += jump
print("step", step)

if __name__ == '__main__':
iterator = jump_range(10)
print(next(iterator)) # 0
print(iterator.send(4)) # jump4; step4; 4
print(next(iterator)) # jump None; step5; 5
print(iterator.send(-1)) # jump -1; step4; 4

ÔÚ Python3.3 ÖУ¬Éú³ÉÆ÷ÓÖÒýÈëÁË yield from ¹Ø¼ü×Ö£¬yield from ʵÏÖÁËÔÚÉú³ÉÆ÷ÄÚµ÷ÓÃÁíÍâÉú³ÉÆ÷µÄ¹¦ÄÜ£¬¿ÉÒÔÇáÒ×µÄÖØ¹¹Éú³ÉÆ÷£¬±ÈÈ罫¶à¸öÉú³ÉÆ÷Á¬½ÓÔÚÒ»ÆðÖ´ÐС£

def gen_3():
yield 3

def gen_234():
yield 2
yield from gen_3()
yield 4

def main():
yield 1
yield from gen_234()
yield 5

for element in main():
print(element) # 1,2,3,4,5

´ÓͼÖпÉÒÔ¿´³ö yield from µÄÌØµã¡£Ê¹Óà itertools.chain ¿ÉÒÔÒÔÉú³ÉÆ÷Ϊ×îС×éºÏ×Ó½øÐÐÁ´Ê½×éºÏ£¬Ê¹Óà itertools.cycle ¿ÉÒÔ¶Ôµ¥¶ÀÒ»¸öÉú³ÉÆ÷Ê×βÏà½Ó£¬¹¹ÔìÒ»¸öÑ­»·Á´¡£

ʹÓà yield from ʱ¿ÉÒÔÔÚÉú³ÉÆ÷ÖÐ´ÓÆäËûÉú³ÉÆ÷ yield Ò»¸öÖµ£¬ÕâÑù²»Í¬µÄÉú³ÉÆ÷Ö®¼ä¿ÉÒÔ»¥ÏàͨÐÅ£¬ÕâÑù¹¹Ôì³öµÄÉú³ÉÁ´¸ü¼Ó¸´ÔÓ£¬µ«Éú³ÉÁ´×îС×éºÏ×ÓµÄÁ£¶ÈÈ´¾«Ï¸ÖÁµ¥¸ö yield ¶ÔÏó¡£

2. ¶ÌÔݵÄasynico.coroutine Óëyield from

ÓÐÁËPython3.3ÖÐÒýÈëµÄyield from ÕâÏ¾ß£¬Python3.4 ÖÐмÓÈëÁËasyncio¿â£¬²¢ÌṩÁËÒ»¸öĬÈϵÄevent loop¡£Python3.4ÓÐÁË×ã¹»µÄ»ù´¡¹¤¾ß½øÐÐÒì²½²¢·¢±à³Ì¡£

²¢·¢±à³ÌͬʱִÐжàÌõ¶ÀÁ¢µÄÂß¼­Á÷£¬Ã¿¸öЭ³Ì¶¼ÓжÀÁ¢µÄÕ»¿Õ¼ä£¬¼´Ê¹ËüÃÇÊǶ¼¹¤×÷ÔÚͬ¸öÏß³ÌÖеġ£ÒÔÏÂÊÇÒ»¸öʾÀý´úÂ룺

import asyncio
import aiohttp

@asyncio.coroutine
def fetch_page(session, url):
response = yield from session.get(url)
if response.status == 200:
text = yield from response.text()
print(text)
loop = asyncio.get_event_loop()

session = aiohttp.ClientSession(looploop=loop)

tasks = [
asyncio.ensure_future(
fetch_page(session, "http://bigsec.com/products/redq/")),
asyncio.ensure_future(
fetch_page(session, "http://bigsec.com/products/warden/"))
]

loop.run_until_complete(asyncio.wait(tasks))
session.close()
loop.close()

ÔÚ Python3.4 ÖУ¬asyncio.coroutine ×°ÊÎÆ÷ÊÇÓÃÀ´½«º¯Êýת»»ÎªÐ­³ÌµÄÓï·¨£¬ÕâÒ²ÊÇ Python µÚÒ»´ÎÌṩµÄÉú³ÉÆ÷Э³Ì ¡£Ö»ÓÐͨ¹ý¸Ã×°ÊÎÆ÷£¬Éú³ÉÆ÷²ÅÄÜʵÏÖЭ³Ì½Ó¿Ú¡£Ê¹ÓÃЭ³Ìʱ£¬ÄãÐèҪʹÓà yield from ¹Ø¼ü×Ö½«Ò»¸ö asyncio.Future ¶ÔÏóÏòÏ´«µÝ¸øÊ¼þÑ­»·£¬µ±Õâ¸ö Future ¶ÔÏó»¹Î´¾ÍÐ÷ʱ£¬¸ÃЭ³Ì¾ÍÔÝʱ¹ÒÆðÒÔ´¦ÀíÆäËûÈÎÎñ¡£Ò»µ© Future ¶ÔÏóÍê³É£¬Ê¼þÑ­»·½«»áÕì²âµ½×´Ì¬±ä»¯£¬»á½« Future ¶ÔÏóµÄ½á¹ûͨ¹ý send ·½·¨·½·¨·µ»Ø¸øÉú³ÉÆ÷Э³Ì£¬È»ºóÉú³ÉÆ÷»Ö¸´¹¤×÷¡£

ÔÚÒÔÉϵÄʾÀý´úÂëÖУ¬Ê×ÏÈʵÀý»¯Ò»¸ö eventloop£¬²¢½«Æä´«µÝ¸ø aiohttp.ClientSession ʹÓã¬ÕâÑù session ¾Í²»Óô´½¨×Ô¼ºµÄʼþÑ­»·¡£

´Ë´¦ÏÔʽµÄ´´½¨ÁËÁ½¸öÈÎÎñ£¬Ö»Óе± fetch_page È¡µÃ api.bigsec.com Á½¸ö url µÄÊý¾Ý²¢´òÓ¡Íê³Éºó£¬ËùÓÐÈÎÎñ²ÅÄܽáÊø£¬È»ºó¹Ø±Õ session Óë loop£¬ÊÍ·ÅÁ¬½Ó×ÊÔ´¡£

µ±´úÂëÔËÐе½ response = yield from session.get(url)´¦£¬fetch_page Э³Ì±»¹ÒÆð£¬ÒþʽµÄ½«Ò»¸ö Future ¶ÔÏ󴫵ݸøÊ¼þÑ­»·£¬Ö»Óе± session.get() Íê³Éºó£¬¸ÃÈÎÎñ²ÅËãÍê³É¡£

session.get() ÄÚ²¿Ò²ÊÇЭ³Ì£¬ÆäÊý¾Ý´«ÊäλÓÚÔÚ´æ´¢Æ÷ɽ×îÂýµÄÍøÂç²ã¡£µ± session.get Íê³Éʱ£¬È¡µÃÁËÒ»¸ö response ¶ÔÏó£¬ÔÙ´«µÝ¸øÔ­À´µÄ fetch_page Éú³ÉÆ÷Э³Ì£¬»Ö¸´Æä¹¤×÷״̬¡£

ΪÁËÌá¸ßËÙ¶È£¬´Ë´¦ get ·½·¨½«È¡µÃ http header Óë body ·Ö½â³ÉÁ½´ÎÈÎÎñ£¬¼õÉÙÒ»´ÎÐÔ´«ÊäµÄÊý¾ÝÁ¿¡£response.text() ¼´ÊÇÒì²½ÇëÇó http body¡£

ʹÓà dis ¿â²é¿´ fetch_page Э³ÌµÄ×Ö½ÚÂ룬GET_YIELD_FROM_ITER ÊÇ yield from µÄ²Ù×÷Âë:

In [4]: import dis

In [5]: dis.dis(fetch_page)
0 LOAD_FAST 0 (session)
2 LOAD_ATTR 0 (get)
4 LOAD_FAST 1 (url)
6 CALL_FUNCTION 1
8 GET_YIELD_FROM_ITER
10 LOAD_CONST 0 (None)
12 YIELD_FROM
14 STORE_FAST 2 (response)

16 LOAD_FAST 2 (response)
18 LOAD_ATTR 1 (status)
20 LOAD_CONST 1 (200)
22 COMPARE_OP 2 (==)
24 POP_JUMP_IF_FALSE 48

26 LOAD_FAST 2 (response)
28 LOAD_ATTR 2 (text)
30 CALL_FUNCTION 0
32 GET_YIELD_FROM_ITER
34 LOAD_CONST 0 (None)
36 YIELD_FROM
38 STORE_FAST 3 (text)

40 LOAD_GLOBAL 3 (print)
42 LOAD_FAST 3 (text)
44 CALL_FUNCTION 1
46 POP_TOP
>> 48 LOAD_CONST 0 (None)
50 RETURN_VALUE

3. asyncÓë await¹Ø¼ü×Ö

Python3.5 ÖÐÒýÈëÁËÕâÁ½¸ö¹Ø¼ü×ÖÓÃÒÔÈ¡´ú asyncio.coroutine Óë yield from£¬´ÓÓïÒåÉ϶¨ÒåÁËÔ­ÉúЭ³Ì¹Ø¼ü×Ö£¬±ÜÃâÁËʹÓÃÕß¶ÔÉú³ÉÆ÷Э³ÌÓëÉú³ÉÆ÷µÄ»ìÏý¡£Õâ¸ö½×¶Î(3.0-3.4)ʹÓà Python µÄÈ˲»¶à£¬Òò´ËÀúÊ·°ü¸¤²»ÖØ£¬¿ÉÒÔ½øÐÐһЩ½Ï´óµÄ¸ïС£

await µÄÐÐΪÀàËÆ yield from£¬µ«ÊÇËüÃÇÒì²½µÈ´ýµÄ¶ÔÏó²¢²»Ò»Ö£¬yield from µÈ´ýµÄÊÇÒ»¸öÉú³ÉÆ÷¶ÔÏ󣬶øawait½ÓÊÕµÄÊǶ¨ÒåÁË__await__·½·¨µÄ awaitable ¶ÔÏó¡£

ÔÚ Python ÖУ¬Ð­³ÌÒ²ÊÇ awaitable ¶ÔÏó£¬collections.abc.Coroutine ¶ÔÏó¼Ì³Ð×Ô collections.abc.Awaitable¡£

Òò´Ë£¬½«ÉÏһС½ÚµÄʾÀý´úÂë¸Äд³É£º

import asyncio
import aiohttp

async def fetch_page(session, url):
response = await session.get(url)
if response.status == 200:
text = await response.text()
print(text)

loop = asyncio.get_event_loop()
session = aiohttp.ClientSession(looploop=loop)

tasks = [
asyncio.ensure_future(
fetch_page(session, "http://bigsec.com/products/redq/")),
asyncio.ensure_future(
fetch_page(session, "http://bigsec.com/products/warden/"))
]
loop.run_until_complete(asyncio.wait(tasks))
session.close()
loop.close()

´Ó Python ÓïÑÔ·¢Õ¹µÄ½Ç¶ÈÀ´Ëµ£¬async/await ²¢·ÇÊǶàôΰ´óµÄ¸Ä½ø£¬Ö»ÊÇÒý½øÁËÆäËûÓïÑÔÖгÉÊìµÄÓïÒ壬Э³ÌµÄ»ùʯ»¹ÊÇÔÚÓÚ eventloop ¿âµÄ·¢Õ¹£¬ÒÔ¼°Éú³ÉÆ÷µÄÍêÉÆ¡£´Ó½á¹¹Ô­Àí¶øÑÔ£¬asyncio ʵÖʵ£µ±µÄ½ÇÉ«ÊÇÒ»¸öÒì²½¿ò¼Ü£¬async/await ÊÇΪÒì²½¿ò¼ÜÌṩµÄ API£¬ÒòΪʹÓÃÕßĿǰ²¢²»ÄÜÍÑÀë asyncio »òÆäËûÒì²½¿âʹÓà async/await ±àдЭ³Ì´úÂë¡£¼´Ê¹Óû§¿ÉÒÔ±ÜÃâÏÔʽµØÊµÀý»¯Ê¼þÑ­»·£¬±ÈÈçÖ§³Ö asyncio/await Óï·¨µÄЭ³ÌÍøÂç¿â curio£¬µ«ÊÇÍÑÀëÁË eventloop ÈçÐÄÔà°ãµÄÇý¶¯×÷Óã¬async/await ¹Ø¼ü×Ö±¾ÉíÒ²ºÁÎÞ×÷Óá£

ËÄ¡¢async/awaitµÄʹÓÃ

1. Future

²»Óûص÷·½·¨±àдÒì²½´úÂëºó£¬ÎªÁË»ñÈ¡Òì²½µ÷ÓõĽá¹û£¬ÒýÈëÒ»¸ö Future δÀ´¶ÔÏó¡£Future ·â×°ÁËÓë loop µÄ½»»¥ÐÐΪ£¬add_done_callback ·½·¨Ïò epoll ×¢²á»Øµ÷º¯Êý£¬µ± result ÊôÐԵõ½·µ»ØÖµºó£¬»áÔËÐÐ֮ǰע²áµÄ»Øµ÷º¯Êý£¬ÏòÉÏ´«µÝ¸ø coroutine¡£µ«ÊÇ£¬Ã¿Ò»¸ö½ÇÉ«¸÷ÓÐ×Ô¼ºµÄÖ°Ôð£¬Óà Future ÏòÉú³ÉÆ÷ send result ÒÔ»Ö¸´¹¤×÷״̬²¢²»ºÏÊÊ£¬Future ¶ÔÏó±¾ÉíµÄÉú´æÖÜÆÚ±È½Ï¶Ì£¬Ã¿Ò»´Î×¢²á»Øµ÷¡¢²úÉúʼþ¡¢´¥·¢»Øµ÷¹ý³Ìºó¹¤×÷ÒѾ­Íê³É¡£ËùÒÔÕâÀïÓÖÐèÒªÔÚÉú³ÉÆ÷Э³ÌÓë Future ¶ÔÏóÖÐÒýÈëÒ»¸öеĶÔÏó Task£¬¶ÔÉú³ÉÆ÷Э³Ì½øÐÐ״̬¹ÜÀí¡£

2. Task

Task£¬¹ËÃû˼Ò壬ÊÇά»¤Éú³ÉÆ÷Э³Ì״̬´¦ÀíÖ´ÐÐÂß¼­µÄµÄÈÎÎñ£¬Task ÄÚµÄ_step ·½·¨¸ºÔðÉú³ÉÆ÷Э³ÌÓë EventLoop ½»»¥¹ý³ÌµÄ×´Ì¬Ç¨ÒÆ:ÏòЭ³Ì send Ò»¸öÖµ£¬»Ö¸´Æä¹¤×÷״̬£¬Ð­³ÌÔËÐе½¶Ïµãºó£¬µÃµ½ÐµÄδÀ´¶ÔÏó£¬ÔÙ´¦Àí future Óë loop µÄ»Øµ÷×¢²á¹ý³Ì¡£

3. Loop

ʼþÑ­»·µÄ¹¤×÷·½Ê½ÓëÓû§ÉèÏë´æÔÚһЩƫ²î£¬ÀíËùµ±È»µÄÈÏÖªÓ¦ÊÇÿ¸öÏ̶߳¼¿ÉÒÔÓÐÒ»¸ö¶ÀÁ¢µÄ loop¡£µ«ÊÇÔÚÔËÐÐÖУ¬ÔÚÖ÷Ïß³ÌÖвÅÄÜͨ¹ý asyncio.get_event_loop() ´´½¨Ò»¸öÐ嵀 loop£¬¶øÔÚÆäËûÏß³Ìʱ£¬Ê¹Óà get_event_loop() È´»áÅ×´í£¬ÕýÈ·µÄ×ö·¨Ó¦¸ÃÊÇ asyncio.set_event_loop() ½øÐе±Ç°Ïß³ÌÓë loop µÄÏÔʽ°ó¶¨¡£ÓÉÓÚ loop µÄÔË×÷ÐÐΪ²¢²»ÊÜ Python ´úÂëµÄ¿ØÖÆ£¬ËùÒÔÎÞ·¨Îȶ¨µÄ½«Ð­³ÌÍØÕ¹µ½¶àÏß³ÌÖÐÔËÐС£

Э³ÌÔÚ¹¤×÷ʱ£¬²¢²»Á˽âÊÇÄĸö loop ÔÚ¶ÔÆäµ÷¶È£¬¼´Ê¹µ÷Óà asyncio.get_event_loop() Ò²²»Ò»¶¨ÄÜ»ñÈ¡µ½ÕæÕýÔËÐеÄÄǸö loop¡£Òò´ËÔÚ¸÷ÖÖ¿â´úÂëÖУ¬ÊµÀý»¯¶ÔÏóʱ¶¼±ØÐëÏÔʽµÄ´«µÝµ±Ç°µÄ loop ÒÔ½øÐа󶨡£

4. ÁíÒ»¸öFuture

Python ÀïÁíÒ»¸ö Future ¶ÔÏóÊÇ concurrent.futures.Future£¬Óë asyncio.Future »¥²»¼æÈÝ£¬µ«ÈÝÒײúÉú»ìÏý¡£concurrent.futures ÊÇÏ̼߳¶µÄ Future ¶ÔÏ󣬵±Ê¹Óà concurrent.futures.Executor ½øÐжàÏ̱߳à³ÌʱÓÃÓÚÔÚ²»Í¬µÄ thread Ö®¼ä´«µÝ½á¹û¡£

5. ÏÖ½×¶ÎasyncioÉú̬·¢Õ¹µÄÀ§ÄÑ

ÓÉÓÚÕâÁ½¸ö¹Ø¼ü×ÖÔÚ2014Äê·¢²¼µÄPython3.5Öвű»ÒýÈ룬·¢Õ¹ÀúÊ·½Ï¶Ì£¬ÔÚPython2ÓëPython3¸îÁѵĴ󻷾³Ï£¬Éú̬»·¾³µÄ½¨Á¢²¢²»ÍêÉÆ;

¶ÔÓÚʹÓÃÕßÀ´Ëµ£¬Ï£ÍûµÄÂß¼­ÊÇÒýÈëÒ»¸ö¿âÈ»ºóµ÷Óò¢»ñÈ¡½á¹û£¬²¢²»¹ØÐĵÚÈý·½¿âµÄÄÚ²¿Âß¼­¡£È»¶øÊ¹ÓÃЭ³Ì±àдÒì²½´úÂëʱÐèÒª´¦ÀíÓëʼþÑ­»·µÄ½»»¥¡£¶ÔÓÚÒì²½¿âÀ´Ëµ£¬Æä¶ÔÍâ·â×°ÐÔ²¢²»Äܴﵽͬ²½¿âÄÇô¸ß¡£Òì²½±à³Ìʱ£¬Óû§Í¨³£Ö»»áÑ¡ÔñÒ»¸öµÚÈý·½¿âÀ´´¦ÀíËùÓÐHTTPÂß¼­¡£µ«ÊDz»Í¬µÄÒ첽ʵÏÖ·½·¨²»Ò»Ö£¬»¥²»¼æÈÝ£¬·ÖÆç×è°­ÁËÉçÇø×³´ó;

Òì²½´úÂëËäÈ»¿ì£¬µ«²»ÄÜ×èÈû£¬Ò»µ©×èÈûÕû¸ö³ÌÐòʧЧ¡£Ê¹ÓöàÏ̻߳ò¶à½ø³ÌµÄ·½Ê½½«µ÷¶ÈȨ½»¸ø²Ù×÷ϵͳ£¬Î´Ãâ²»ÊÇÒ»ÖÖ×ÔÎÒ±£»¤;

6. һЩ¸öÈË¿´·¨

Æäʵ˵ÁËÕâô¶à£¬¸öÈ˾õµÃ asyncio ËäÈ»¸ü¼ÓÓÅÑÅ£¬È´Êµ¼ÊʹÓÃÉϲ¢²»ÊÇÏñ±íÃæ¿´ÆðÀ´µÄÄÇôÃÀºÃ¡£Ê×ÏÈ£¬Ëü²»ÊÇÌØ±ðµÄ¿ì(¾Ý˵±È gevent ¿ìÒ»±¶)£¬È´ÒýÈëÁ˸ü¶àµÄ¸´ÔÓÐÔ£¬¶øÇÒ´Ó´íÎóÐÅÏ¢ debug ¸ü¼ÓÀ§ÄÑ¡£Æä´Î£¬ÕâÌ×½â¾ö·½°¸²¢²»³ÉÊ죬×î½ü 3.4¡¢3.5¡¢3.6 µÄÈý¸ö°æ±¾£¬Ð­³ÌÒ²Óи÷ÖÖµÄϸ½Ú±ä»¯£¬Ò²±äµÃÔ½À´Ô½¸´ÔÓ£¬³ÌÐòÔ±±ØÐëËæÊ±¹Ø×¢ÓïÑԵı仯²ÅÄÜͬ²½¡£ÁîÈËÒÉ»óµÄÊÇΪʲô Python Ò»¶¨Òª¼á³ÖÓÃÉú³ÉÆ÷À´ÊµÏÖЭ³Ì£¬×îºóÓÖ½«Éú³ÉÆ÷ÓëЭ³Ì½øÐÐÐÂÀÏ»®¶Ï£¬Ï¸½ÚȴδµÃµ½ÆÁ±Î?ÒÔĿǰµÄ³ÉÊì¶ÈÀ´¿´£¬µ±ÄãдЭ³Ì´úÂëʱ£¬±ØÐëÏÈÈ¥Àí½âЭ³Ì¡¢Éú³ÉÆ÷µÄÇø±ð£¬future ¶ÔÏóÓë task ¶ÔÏóµÄÖ°ÄÜ£¬loop µÄ×÷Óá£×ÜÖ®£¬Ä¿Ç°ÔÚÉú²ú»·¾³ÖÐʹÓà asyncio ¼¼ÊõÕ»À´½â¾öÎÊÌâ²¢²»Îȶ¨£¬Õâ¸öÉú̬»¹ÐèÒª³Ö¾ÃµÄ·¢Õ¹²ÅÄܳÉÊì¡£

×÷Ϊ³ÌÐòÔ±£¬ÔÚÒ»ÃÅÓïÑÔÉÏÉîÈëͬÑù¿ÉÒÔ´øÀ´ÖªÊ¶µÄ¹ã¶È¡£²»Í¬ÓïÑÔÓв»Í¬µÄÐÔ¸ñ£¬ºÏÊʵŤ¾ß½â¾öºÏÊʵÄÎÊÌ⣬¶øÒÔÒ»Ãû Python ³ÌÐòÔ±µÄÊÓ½ÇÀ´¿´£¬´ó¿É²»±Ø¼á³Ö¼ÄÏ£ÍûÓÚ asyncio ½â¾ö Python µÄÐÔÄÜÎÊÌ⣬°ÑÔÚ×ÝÏòÉϸ㶮 asyncio ºÍÕâÒ»Ì×Э³Ìϸ½ÚËùÐèµÄʱ¼äÄÃÀ´ºáÏòѧϰ Golang£¬Ñ°Çó¸üºÏÊʸü¼òµ¥µÄ½â¾ö·½°¸£¬´úÂëÒ²¿ÉÒÔÉÏÏßÁË¡£

 

   
4099 ´Îä¯ÀÀ       28
Ïà¹ØÎÄÕÂ

ÊÖ»úÈí¼þ²âÊÔÓÃÀýÉè¼ÆÊµ¼ù
ÊÖ»ú¿Í»§¶ËUI²âÊÔ·ÖÎö
iPhoneÏûÏ¢ÍÆËÍ»úÖÆÊµÏÖÓë̽ÌÖ
AndroidÊÖ»ú¿ª·¢£¨Ò»£©
Ïà¹ØÎĵµ

Android_UI¹Ù·½Éè¼Æ½Ì³Ì
ÊÖ»ú¿ª·¢Æ½Ì¨½éÉÜ
androidÅÄÕÕ¼°ÉÏ´«¹¦ÄÜ
Android½²ÒåÖÇÄÜÊÖ»ú¿ª·¢
Ïà¹Ø¿Î³Ì

Android¸ß¼¶Òƶ¯Ó¦ÓóÌÐò
Androidϵͳ¿ª·¢
AndroidÓ¦Óÿª·¢
ÊÖ»úÈí¼þ²âÊÔ