å®éã®Stackless and Concurrenceæ©èœã«é²ãåã«ãè€æ°ã®åææ¥ç¶ãåŠçãããããã¯ãŒã¯ã¢ããªã±ãŒã·ã§ã³ãèšè¿°ããæãç°¡åãªæ¹æ³ãæ€èšããŠãã ããã
socket() bind() listen() accept() fork() -> read() write() ... close()
æ°ããçä¿¡æ¥ç¶ããšã«ãããã»ã¹ã¯forkïŒïŒãä»ããŠã³ããŒãäœæããŸãã ããã¯éåžžã«é«äŸ¡ãªæ¹æ³ã§ãããããã«ããã»ã¹éã®åæã«åé¡ããããŸãã åçŽãªã±ãŒã¹ã§ã¯ã芪ããã»ã¹ãšåããã»ã¹ã®éã«ãã€ããäœæããããŒã¿ãã·ãªã¢ã«åããããšã§è§£æ±ºããŸãã ããè€éãªãã®ã«ã¯ãããã»ã¹éåæããªããã£ããå¿
èŠã§ãã ããã»ã¹ã®äœæãç Žæ£ãããã³åãæ¿ãã®ã³ã¹ãã«ã€ããŠããã«æãåºããŠã¿ãŸãããã ãããã¯ãã¡ã¢ãªãšåŠçèœåã®äž¡æ¹ã§éåžžã«ãªãœãŒã¹ãæ¶è²»ããæäœã§ãã ãããã£ãŠã倿°ã®åææ¥ç¶ãåŠçããããšã¯éåžžã«å°é£ã§ãããã
ãã ãããã®ã¢ãããŒãã«ã¯1ã€ã®éèŠãªå©ç¹ããããŸã-ã³ãŒãã¯éåžžã«åçŽã§ãã ã¢ããªã±ãŒã·ã§ã³ã®ããžãã¯ã¯ã察å¿ããèšèªæ§é ã«çŽæ¥è»¢éãããŸã-ãµã€ã¯ã«ã§ãããã¯ãŒã¯ãä»ããŠããŒã¿ãåä¿¡ããå¿
èŠãããå Žåãããã¯ãµã€ã¯ã«æŒç®åã«ãªããŸãã æåã«1ã€ã®ã¢ã¯ã·ã§ã³ãå®è¡ããæ¬¡ã«å¥ã®ã¢ã¯ã·ã§ã³ãå®è¡ããå¿
èŠãããå Žåãããã¯ããã°ã©ã å
ã®2ã€ã®é£ç¶ããã¹ããŒãã¡ã³ããªã©ã«ãªããŸãã
æ°ããããã»ã¹ãäœæãã代ããã«ãåãããã»ã¹å
ã«å¥ã®ã¹ã¬ãããäœæãããšãããã€ãã®åé¡ãè§£æ¶ãããŸããã¹ã¬ããéã§ããŒã¿ã亀æããã®ãã¯ããã«ç°¡åã«ãªããŸãã å
±éãªããžã§ã¯ãã«ã¡ã¢ãªãå²ãåœãŠãã«ã¯ãèšèªã®éåžžã®ææ®µã䜿çšããã ãã§ååã§ããã¹ã¬ããéã§å
±éãªããžã§ã¯ããžã®ãªã³ã¯ã転éããŠãå®å
šã§ãããã·ãªã¢ã«åã§ãªãœãŒã¹ã浪費ããŸããã ããã«ãããå€ãã®ããã»ããµãªãœãŒã¹ãç¯çŽãããŸãããæç€ºçãªåæãšå
±æãªããžã§ã¯ããžã®ã¢ã¯ã»ã¹ã®å¿
èŠæ§ãæé€ãããããã§ã¯ãããŸããã ããã«ãåãªãã¬ãŒãã£ã³ã°ã·ã¹ãã ã¹ã¬ããã«ã¯ç¬èªã®ã¹ã¿ãã¯ããããæ°ãããã€ãã®ã¡ã¢ãªãå æããŸããããã«åææ¥ç¶æ°ãæãããšãæ°çŸã¡ã¬ãã€ããå æããå¯èœæ§ããããŸãã ããããã¡ã¢ãªã®æå€±ã調æŽã§ããå ŽåïŒå®äŸ¡ïŒãã¹ã¬ããã®äœæãšç Žæ£ãã³ã³ããã¹ãã®åãæ¿ããåæã®èšç®ã³ã¹ãã¯ââéåžžã«é¡èã«ãªããŸãã ããã«ãGILã®åªãã¯Pythonã«ããã£ãŠããããããã«ãã¹ã¬ããã¢ããªã±ãŒã·ã§ã³ã®æå¹æ§ãããã«äœäžããŸãã
çç£æ§ã®åäžã«ããããšã³ãžãã¢ãªã³ã°ã®æ¬¡ã®ã¹ãããã¯ãæéç¶æ
ãã·ã³ã®æç€ºçãªå²ãåœãŠã«åºã¥ãã·ã³ã°ã«ã¹ã¬ããã¢ããªã±ãŒã·ã§ã³ã§ããã 忥ç¶ã¯ãªãŒãããã³ã«ãã£ãŠè¡šãããåç¶æ
ã§å
¥åããŒã¿ãäœããã®æ¹æ³ã§åŠçãããããã«ç¶æ
ãå€åããŸãã ãã·ã³ã®ç¶æ
ã¯å°ããªããŒã¿æ§é ã«ãããªãããããªãã¬ãŒãã£ã³ã°ã·ã¹ãã ã®åã
ã®ã¹ã¬ãããããããããã®äœæãä¿åãããã³ç Žå£ãã¯ããã«é«éã§ãã ãããŠãã¹ã¬ãããããã¯ããã«å°ãªãã¡ã¢ãªãå æããŸãã
æéç¶æ
ãã·ã³ã®æç€ºçãªå²ãåœãŠã«åºã¥ãã¢ããªã±ãŒã·ã§ã³ã§ã¯ãã¡ã€ã³ã«ãŒãã¯ãã€ãã³ãã®ãã¹ãŠã®éããŠããæ¥ç¶ã®èª¿æ»ã§ããããŒã¿ãå°çããããšã©ãŒãçºçããããŸãã¯éä¿¡ãããã¡ãŒã®ã¹ããŒã¹ãè§£æŸãããŸããã ã€ãã³ãããšã«ãã¹ããŒããã·ã³ã§ãã³ãã©ãŒãåŒã³åºãããŸãã ãã®èª¿æ»ãæé©åããïŒãããŠäœäžãã®æ¥ç¶ããã°ããããŒãªã³ã°ããã®ã¯ç°¡åãªäœæ¥ã§ã¯ãããŸããïŒããã«ãææ°ã®ãªãã¬ãŒãã£ã³ã°ã·ã¹ãã ã¯ããŸããŸãªéåžžã«å¹æçã§ãããä»ã®ã€ã³ã¿ãŒãã§ã€ã¹ïŒkqueueãepollãªã©ïŒãšäºææ§ããããŸãã ããŒã¿ãã«ãããã¯ãŒã¯ã¢ããªã±ãŒã·ã§ã³ãäœæããããã«ãããã°ã©ãããæ¥ç¶ããŒãªã³ã°ã®å®è£
ã®è©³çްãé ãlibeventãªã©ã®ç¹å¥ãªã©ã€ãã©ãªãéçºãããŸããã
ãã ããæéç¶æ
ãã·ã³ãæç€ºçã«æå®ãããšïŒåç¶æ
ã¯ããã°ã©ã ã®åå¥ã®ã»ã¯ã·ã§ã³ã«ãªããŸãïŒãã¢ããªã±ãŒã·ã§ã³ã®æ§é ã¯è€éã§èªã¿ã«ãããªããŸãã å®éããã®å Žåã®ç¶æ
éã®é·ç§»ã¯gotoã¹ããŒãã¡ã³ãã®äœ¿çšã«äŒŒãŠããŸã-ç¶æ
ãå€åããå Žåãæ¬¡ã®ç¶æ
ãã³ãã©ãŒãé
眮ãããŠãããœãŒã¹å
šäœã§å床æ€çŽ¢ããå¿
èŠããããŸãã ããã§ã¯åçŽãªãããã¯ãŒã¯ãããã³ã«ãå®è£
ãããµã³ãã«ã»ã¢ããªã±ãŒã·ã§ã³ã»ãã¬ãŒã ã¯ãŒã¯ã¯ã次ã®ãšããã§ãã
select() -> read_ready -> read(cmd) if state == "STATE1": if cmd == "CMD1": state = "STATE2" else: invalid_command() elif state == "STATE2": if cmd == "CMD2": state = "STATE1" else: invalid_command()
åãã³ãã©ãŒããããã¯ãããããšã¯ãããŸãããããã«ãããéåæããŒã¿åŠçãå®çŸãããŸãã ãã®ã¢ãŒããã¯ãã£ã§ãã¢ããªã±ãŒã·ã§ã³ãããŒã¿ããŒã¹ã«èŠæ±ãè¡ãå¿
èŠãããå ŽåãèŠæ±ãéä¿¡ããå¿çã®åŸ
æ©ç¶æ
ã«é²ã¿ãå¶åŸ¡ãã¡ã€ã³ã«ãŒãã«æ»ãå¿
èŠããããŸãã ããŒã¿ããŒã¹ããå¿çãæ¥ããšãããŒã¿ãåä¿¡ããŠââåŠçãããã³ãã©ãŒãåŒã³åºãããŸãã èŠæ±/å¿çã¹ããŒã ããã«ããã§ãŒãºã®å ŽåïŒããšãã°ãSMTPã§ãæ¥ç¶ãåŒã³åºããå¶åŸ¡ãäžããæ¥ç¶ã®ç¢ºç«ãåŸ
æ©ããããŒã¿ã®åŸ
æ©ãéå§ãããµãŒããŒããHELOãåŸ
ã¡ãHELOãéä¿¡ããå¶åŸ¡ãäžããå¿çãåŸ
ã¡ãå¿çãèªããªã©ïŒããã®åŸæç€ºçãªèšæã¯ããã°ã©ãã®æªå€¢ã«ãªããŸãã
å®è£
ã¯è€éã§ããããã®ã¢ãããŒãã«ã¯åŠå®ã§ããªãå©ç¹ããããŸããæ¥ç¶ãã³ãã©ãŒéã®åæã¯å®è³ªçã«å¿
èŠãããŸããã å®éããããã®éã®åãæ¿ãã¯å調çã«è¡ãããŸã-ã¡ã€ã³ãµã€ã¯ã«ãæç¢ºã«å¶åŸ¡ã§ããç¬éã«ã®ã¿ã ãã³ãã©ãŒã¯ã©ã®ãããªç¶æ³ã§ãäžæã§ããŸãããã€ãŸããã°ããŒãã«ãªããžã§ã¯ãã«ã¢ã¯ã»ã¹ããããã®ãã¹ãŠã®æäœã¯ã¢ãããã¯ã§ããããšãä¿èšŒãããŸãã ãã¥ãŒããã¯ã¹ãã»ããã©ããã®ä»ã®ãã©ãã«ãå¿ãã貎éãªããã»ããµã¯ããã¯ãæ¶è²»ããŠããŸããã
ã¹ã¿ãã¯ã¬ã¹
ã¹ããŒããã·ã³ã®ããã©ãŒãã³ã¹ãšæåã®ãœãªã¥ãŒã·ã§ã³ã®ã·ã³ãã«ããçµã¿åãããæ¹æ³ããããŸãã ãã®ããã«ã¯ãStackless Pythonãå¿
èŠã§ãã Stackless Pythonã¯ãPythonã€ã³ã¿ãŒããªã¿ãŒã®æ¹è¯çã§ãã ããã°ã©ããŒã¯ãåæããªããã£ãã®ããã©ãŒãã³ã¹ãç ç²ã«ããããšãªããç«¶åç¶æ
ã®åé¡ãªãã«ããã«ãã¹ã¬ããããã°ã©ãã³ã°ãå©çšã§ããŸãã å®äŸ¡ã§è»œéã®Stacklessãã€ã¯ããããŒãæ£ãã䜿çšãããšãããã°ã©ã ã®æ§é ãæ¹åããã³ãŒããèªã¿ãããããŠãããã°ã©ãã®çç£æ§ãåäžãããããšãã§ããŸãã ä»çµã¿ãèŠãŠã¿ãŸãããã
ããã°ã©ããŒã®èгç¹ããèŠããšãã¿ã¹ã¯ã¬ããïŒã¹ã¿ãã¯ã¬ã¹çšèªã§ãã€ã¯ããããŒïŒãäœæããããšã¯ãæ°ãããªãã¬ãŒãã£ã³ã°ã·ã¹ãã ã¹ã¬ãããäœæããããšãšåãã§ãïŒstackless.taskletïŒyour_funcïŒïŒ1ã2ã3ïŒã æ°ããã¿ã¹ã¯ã¬ããã®ã³ã³ããã¹ãã§é¢æ°your_funcïŒ1ã2ã3ïŒã®å®è¡ãéå§ããŸãã ãã®é¢æ°ã®å®è¡ã¯ãã¿ã¹ã¯ã¬ãããæç€ºçã«ã«ãŒãã«ã«å¶åŸ¡ãäžãããŸã§ïŒstackless.scheduleïŒïŒïŒããŸãã¯ãããã¯ãããŠãæ
å ±ã®éåä¿¡ãåŸ
æ©ãããŸã§ç¶ç¶ãããŸãã ããšãã°ãã¿ã¹ã¯ã¬ããã¯ãããã¯ãŒã¯ãœã±ããããããŒã¿ãåä¿¡ããããããŸã å©çšã§ããŸããã ãã®æç¹ã§ãã¿ã¹ã¯ã¬ããã¯I / OåŸ
æ©ãã¥ãŒã«å
¥ããå¶åŸ¡ã¯æ¬¡ã®ã¿ã¹ã¯ã¬ããã«é çªã«è»¢éãããŸãã äºæ³ãããããŒã¿ãå°çãããšãæåã®ã¿ã¹ã¯ã¬ãããå¶åŸ¡ãåŒãç¶ããããŒã¿ã®åŠçãç¶è¡ããŸãã
å®éãåãããžãã¯ãæéç¶æ
ãã·ã³ã¹ããŒã ã§æ©èœããŸããïŒå調ãã«ãã¿ã¹ã¯ããœã±ãããããŒãžã£ãŒã䜿çšããå¿
èŠæ§ãããã³å
±éããŒã¿æ§é ã«ã¢ã¯ã»ã¹ããããã®åæããªããã£ããå¿
èŠãªãããšïŒãäž»ãªéãã¯ãã¿ã¹ã¯ãéåžžã®ç·åœ¢Pythonã³ãŒãã§èšè¿°ãããããšã§ãã ããšãã°ããããã¯ãŒã¯ãµãŒãã¹ãžã®åŒã³åºãã¯æ¬¡ã®ããã«èª¬æã§ããŸãã
val = memcached.get("some-object-123") if val is None: res = list(mysql.query("select val from tbl where id=%d", 123)) if len(res): val = res[0] memcached.set("some-object-123", val)
åãããã¯ãŒã¯æäœïŒmemcachedãããŒã¿ããŒã¹ãžã®ã¢ã¯ã»ã¹ãHTTPãªã¯ãšã¹ãã®å®è¡ãSMTPãä»ããé»åã¡ãŒã«ã®éä¿¡ãªã©ïŒã¯ãçµæãåä¿¡ããããŸã§ã¿ã¹ã¯ã¬ãããäžæåæ¢ããŸãã åŸ
ã£ãŠããéãä»ã®ã¿ã¹ã¯ã¬ãããå®è¡ããŸãã
ã¿ã¹ã¯ã¬ããã¯ããã£ãã«ã䜿çšããŠçžäºã«ããŒã¿ãéä¿¡ã§ããŸãã ãã£ãã«ã¯ãéä¿¡ïŒïŒãšåä¿¡ïŒïŒã®2ã€ã®äž»èŠãªã¡ãœãããæã€ãªããžã§ã¯ãã§ãã 1ã€ã®ã¿ã¹ã¯ã¬ãããch.sendïŒsome_objectïŒããŒã¿ããã£ãã«ã«éä¿¡ããå Žåãä»ã®ã¿ã¹ã¯ã¬ããã¯ãã®ããŒã¿ãåä¿¡ã§ããŸãïŒsome_object = ch.receiveïŒïŒã ãã£ãã«ã«ä¿çäžã®ã¿ã¹ã¯ã¬ããããªãå Žåãéä¿¡è
ã¯ããŒã¿ãåä¿¡ããããŸã§ãããã¯ãããŸãã ãŸãããã£ãã«ã«ä¿çäžã®ããŒã¿ããªãå Žåãåä¿¡ã¿ã¹ã¯ã¬ããã¯è¡šç€ºããããŸã§ãããã¯ãããŸãã è€æ°ã®ã¿ã¹ã¯ã¬ããã¯1ã€ã®ãã£ãã«ã䜿çšã§ããåãã£ãã«ã¯ããŒã¿ãéåä¿¡ã§ããŸãã ãã£ãã«ã¯ãã¿ã¹ã¯ã¬ããéã®äž»èŠãªåææ¹æ³ã§ãã ããšãã°ãããŒã¿ããŒã¹ãžã®æ°žç¶çãªæ¥ç¶ã®éãããæ°ããããŒã«ãå®è£
ããå ŽåãããŒã«ããæ¥ç¶ãååŸããæäœã¯æ¬¡ã®ããã«ãªããŸãã
def get(): if len(self._pool): return self._pool.pop(0) else: return self._wait_channel.receive()
ããŒã«ã«ç©ºãæ¥ç¶ãããå Žåããã®ãã¡ã®1ã€ã䜿çšãããŸãã ããã§ãªãå Žåãã¿ã¹ã¯ã¬ããã¯ãã£ãã«ã§ãããã¯ããã誰ããæ¥ç¶ãè§£æŸãããŸã§åŸ
æ©ããŸãã ãã£ãã«ã§ãããã¯ãããã¿ã¹ã¯ã¬ããã¯ãã³ã³ãã¥ãŒã¿ãŒæéã®ããŒããæ¶è²»ããŸããã ãã£ãã«ã®ããžãã¯ã¯ãããŒã¿ããã£ãã«ã«é
眮ããããšããã«ãã¿ã¹ã¯ã¬ãããã¹ã±ãžã¥ãŒã©ã®ãã¥ãŒã«èªåçã«é
眮ããŸãã ããŒã«ã«æ»ã£ãŠé転ååç©ã®æ·å°ã¯æ¬¡ã®ããã«ãªããŸãã
def put(conn): if self._wait_channel.balance < 0: self._wait_channel.send(conn) else: self._pool.append(conn)
ããã£ãã«ã®ãã©ã³ã¹ãããŒãããå°ããå Žåãããã¯ãäžéšã®ã¿ã¹ã¯ã¬ããããã®ãã£ãã«ã§åŸ
æ©ããŠããããšãæå³ããŸãã ãã®å ŽåãããŒã«ã«è¿ãããæ¥ç¶ã¯ãã£ãã«ã«é
眮ãããããããã¿ã¹ã¯ã¬ããã«ãã£ãŠããã«åãåºãããæåã«ãã¥ãŒã«å
¥ã£ãŠããå®è¡ãç¶ç¶ãããŸãã
Stacklessèªäœã¯ãã¿ã¹ã¯ã¬ããã³ã³ããã¹ãã¹ã€ããã³ã°ã·ã¹ãã ãã¹ã±ãžã¥ãŒã©ããã£ãã«ã¡ã«ããºã ãããã³ã¿ã¹ã¯ã¬ããã®ã·ãªã¢ã«åã§ããããããããã£ã¹ã¯ã«ä¿åãããããã¯ãŒã¯ãä»ããŠè»¢éããäžæãããå Žæããå®è¡ãç¶ç¶ã§ããŸãã ãŸããGreenletsããã±ãŒãžããããŸããããã¯ãStacklessã®ç°¡æããŒãžã§ã³ã§ãã ãã€ã¯ããããŒïŒå®éã«ã¯ã°ãªãŒã³ã¬ããïŒã®ã¿ãå®è£
ããã¹ã±ãžã¥ãŒã©ãŒãå«ãæ®ãã®ããžãã¯ã¯ããã°ã©ããŒãæ
åœããŸãã ãã®ãããGreenletsã¯Stacklessããããããã«ïŒ10-25ïŒ
ïŒé
ããªããŸãããç¹å¥ãªããŒãžã§ã³ã®ã€ã³ã¿ãŒããªã¿ãŒãå¿
èŠãšããŸããã
äžŠè¡æ§
å®éã®ãããã¯ãŒã¯ã¢ããªã±ãŒã·ã§ã³ãäœæããã«ã¯ãéããããã³ã°ãœã±ãããæäœããããã®ã©ã€ãã©ãªãå¿
èŠã§ããããã«ã¯ããããã¯ãŒã¯æäœã®ã¿ã¹ã¯ã¬ããããããã¯ãããããã¯ãŒã¯ã€ãã³ãã®çºçæã«ã¿ã¹ã¯ã¬ãããå®è¡ãç¶ãããœã±ãããããŒãžã£ãŒãå«ãŸããŸãã ãã®ãããªã©ã€ãã©ãªãããã€ããããŸãïŒ
åçŽãªäºçްãªããš ã
Eventlet ïŒGreenletsã®ã¿ïŒã
gevent ïŒGreenletsã®ã¿ïŒãããã³
Concurrence ïŒGreenletsãšStacklessïŒã ç§ãäŒãããã®ã¯åŸè
ã«ã€ããŠã§ãã
äžŠè¡æ§ã¯libeventã«åºã¥ããŠããããã®ã¡ã€ã³ã«ãŒããšæ¥ç¶ãããã¡ãŒã·ã¹ãã ã¯Cã§å®è£
ãããŠããããããã¯ãŒã¯æäœã«åªããããã©ãŒãã³ã¹ãæäŸããŸãã ãœã±ãããããŒãžã£ãŒèªäœã«å ããŠãConcurrenceã¯ã¿ã€ããŒãäœæããã¹ãªãŒãïŒsïŒãªã©ã®æ©èœã䜿çšããå€ãã®äžè¬çãªãããã³ã«ïŒHTTPã¯ã©ã€ã¢ã³ããHTTPãµãŒããŒïŒWSGIïŒãMemcachedãMySQL-ã¯ããæ¬åœã®éåæMySQLã¯ã©ã€ã¢ã³ãã©ã€ãã©ãªãå®è£
ããæ©èœãæäŸããŸããXMPPïŒã äžèšã®äŸïŒMemcachedããã³MySQLãžã®åŒã³åºãã䜿çšïŒã¯ãç¹ã«Concurrenceã§èšè¿°ãããŠããŸãã æå°ã®WebãµãŒããŒãäœæããæ¹æ³ã¯æ¬¡ã®ãšããã§ãã
def hello_world(environ, start_response): start_response("200 OK", []) return ["<html>Hello, world!</html>"] def main(): server = WSGIServer(hello_world) server.serve(('localhost', 8000)) dispatch(main)
ãã£ã¹ããã颿°ã¯ãã¡ã€ã³ã®åæå®è¡ã«ãŒããéå§ããã¡ã€ã³é¢æ°ãå®è¡ããæåã®ã¿ã¹ã¯ã¬ããããã¥ãŒã«å
¥ããŸãã æ¬¡ã«ãWSGIServerãèµ·åããæ¥ç¶ãåãå
¥ããŸãã æ¥ç¶ããšã«åå¥ã®ã¿ã¹ã¯ã¬ãããèµ·åãããhello_world颿°ãå®è¡ãããŸãã åŸè
ã¯ä»»æã®è€éãã§ãéåææäœãå«ãŸããŸãã ã·ã¹ãã ããããã®å®äºãåŸ
ã€éãæ°ããæ¥ç¶ã¯åŒãç¶ãåãå
¥ããããŸãã
ä»ãè»èã®ããšã æ®å¿µãªãããåææ§ã¯æŸæ£ããããµããŒããããªããªã£ãããã§ãã äœè
ã¯ããããä»ãã®ãã°ã¬ããŒããå«ãæçŽã«å¿çããŸããã ãããã£ãŠãçºèŠããä¿®æ£ããããã°ãããã³ç¹ã«å®è£
ãããSMTPã¯ã©ã€ã¢ã³ããšThriftãµããŒããåããWebDAVã®HTTP PUTãµããŒããå«ãããã€ãã®è¿œå æ©èœã䜿çšããŠãããŒãžã§ã³ã®Concurrenceãå
¬éããŸããã ãªããžããªã¯
githubã«ãããŸãã
StacklessãConcurrenceããŸãã¯ãã®ä»ã®Pythonéåæããã°ã©ãã³ã°ãã¯ãããžãŒã®äœ¿çšãèšç»ããŠãã人ã¯ã
ru-python-asyncã¡ãŒãªã³ã°ãªã¹ãã«ç»é²ããŠãã ããã
åç
§è³æ
ã¹ã¿ãã¯ã¬ã¹
Python-www.stackless.com
æåäºäŸ
-www.stackless.com/wiki/Applications
äžŠè¡æ§
-opensource.hyves.org/concurrence
Concurrenceã®ç§ã®ããŒãžã§ã³ã¯
github.com/JoyTeam/concurrenceã§ã