ãããã¯ãŒã¯ãµãŒãã¹ãšããŠåäœããéåžžã«å€ãã®ã¢ããªã±ãŒã·ã§ã³ãäœæããå¿ èŠããããŸããã ãããã®ãµãŒãã¹ã¯ãç°ãªãè² è·ã§ç°ãªãèšèªã§èšè¿°ãããŠããããã®ãã³ã«æ°ãããµãŒãã¹ã®å®è£ ã¯ä»¥åã®ãã®ãšå€å°ç°ãªããŸããã habrakatã®äžã§ãç§ã®æèŠã§ã¯ãããã¬ãŒãã³ã°ããµãŒããŒã®å®è£ ãããªãæåããŠããäŸã瀺ããå¿ èŠã«å¿ããŠã³ã¡ã³ããã³ãŒãã«æ·»ä»ããŠããŸãã
å°å ¥èª
ãã®ãããæåã«ãµãŒããŒãå®éã«è¡ãããšã«ã€ããŠããã€ãã®èšèã玹ä»ããŸãã ããã¯ãã¬ãŒãã³ã°ã®äŸã§ãããããã¿ã¹ã¯ã¯éåžžã«ç°¡åã§ããèµ·åæã«ãããŒãã§ãªãã¹ã³ãããœã±ãããäœæããŸãã ã¯ã©ã€ã¢ã³ããæ¥ç¶ããããæ å ±ã®éä¿¡ãéå§ããŸãã æ å ±ãšããŠãã¯ã©ã€ã¢ã³ãã¯ãµãŒããŒã§èšç®ãããæ°åPiã®æ¡ã®ç¡éã¹ããªãŒã ãåãåããŸãã ãµãŒããŒã¯ãå°ãªããšã1ã€ã®ã¯ã©ã€ã¢ã³ããæ¥ç¶ãããŠããå Žåã«ã®ã¿çªå·ãçæããæ¢ã«çæãããã·ãŒã±ã³ã¹ãèšæ¶ããŸãã ãã¹ãŠã®ã¯ã©ã€ã¢ã³ããåæããããšãçæãåæ¢ãããµãŒããŒã¯æ°ããæ¥ç¶ãåŸ ã¡ãŸãã
ãµãŒããŒå®è£ ã¯ã·ã³ã°ã«ã¹ã¬ããã§ãã ãã®ã¢ãããŒãã®å©ç¹ã¯ãäžè¬çã«äœ¿çšãããä»ã®ææ³ã䜿çšããå Žåã«çºçãããå¥åã®ã¹ã¬ãããŸãã¯å¥åã®ã¢ããªã±ãŒã·ã§ã³ã€ã³ã¹ã¿ã³ã¹ãšãã圢ã§è¿œå ã®ãªãŒããŒãããããªãããšã§ãã
æŠããŠããã®éãã¯æ±ºå®çãªãã®ãšã¯ã»ãšãã©èšããŸããã Pythonã¯äŸç¶ãšããŠã€ã³ã¿ãŒããªã¿ãŒèšèªã§ããã䜿çšé åã«å¶éããããŸãããå°æ¥ãã¢ããªã±ãŒã·ã§ã³ã§ãã®ã¢ãŒããã¯ãã£ã«ãä¿åããããã¹ã¬ããã䜿çšããŠã䞊åã³ã³ãã¥ãŒãã£ã³ã°ã¿ã¹ã¯ãå®è¡ã§ããããã«ãªããŸãã
ç¶è¡ããåã«ãã³ãŒããããŠã³ããŒãããŠæµ readingã«èªãããšã匷ããå§ãããŸã ã ãŸããã³ãŒãã¯show codeã§ãªã³ã©ã€ã³ã§è¡šç€ºã§ããŸã ã
ãµãŒããŒãèµ·åããããã«ãUNIXã©ã€ã¯ã·ã¹ãã ã®ãŠãŒã¶ãŒã¯æ¬¡ã®ã³ãã³ããå®è¡ã§ããŸãã
chmod + x ./pypi.py
./pypi.py
ãµãŒããŒã«æ¥ç¶ããã«ã¯ã次ã®ã³ãã³ãã䜿çšã§ããŸãã
telnet 127.0.0.1 45067
ã³ãŒã解æ
ã¢ããªã±ãŒã·ã§ã³ã®äžæ žã¯ã asyncoreã¢ãžã¥ãŒã«ã®ãã£ã¹ããããµã€ã¯ã«ãéå§ããmainïŒïŒé¢æ°ã§ãã
def main ïŒ ïŒ ïŒ
è©ŠããŠãã ãã ïŒ
éåæ ã«ãŒã ïŒ 0.1 ã True ããµãŒããŒïŒ '127.0.0.1' ïŒ ïŒ
KeyboardInterrupt ãé€ã ïŒ
' \ n ByeïŒ-*'ã å°å·ããŸã
sys çµäº ïŒ 0 ïŒ
__name__ == '__main__'ã®å Žå ïŒ
ã¡ã€ã³ïŒ ïŒ
asyncoreã¢ãžã¥ãŒã«ã¯ã4ã€ã®ãªãã·ã§ã³åŒæ°ãåãã«ãŒãé¢æ°ãæäŸããŸããïŒ1ïŒã¿ã€ã ã¢ãŠããïŒ2ïŒéåžžã®selectãããããŒãªã³ã°ã¡ã«ããºã ã®åªå ãã©ã°ãïŒ3ïŒãœã±ããèšè¿°åèŸæžãïŒ4ïŒå埩åæ°ã 3çªç®ã®ãã©ã¡ãŒã¿ãŒã¯éèŠã§ããããã«ãããæ°ããäœæããããµãŒããŒãªããžã§ã¯ããé¢æ°ã«æž¡ããŸããã
ãç¹å¥ãªPythonããžãã¯ãã®ãããã§ãServerã¯ã©ã¹ã¯asyncoreã¢ãžã¥ãŒã«ã®Dispatcherã¯ã©ã¹ãšdictèŸæžã¯ã©ã¹ã®äž¡æ¹ããç¶æ¿ãããŸããããã«ãããæ¥ç¶ããããã¹ãŠã®ã¯ã©ã€ã¢ã³ãã®ãµãŒããŒãœã±ãããšãœã±ããèšè¿°åã®ãªããžããªã®äž¡æ¹ãšããŠæ©èœããŸãã
ãµãŒããŒã¯ã©ã¹å®£èšã®éå§ã¯æ¬¡ã®ãšããã§ãã
ã¯ã©ã¹ãµãŒããŒïŒãã£ã¹ãããã£ãŒã dict ïŒ ïŒ
æžã蟌ã¿å¯èœ= ã©ã ã xïŒ False
def __init__ ïŒ self ãhost = None ãport = 0xB00B ïŒ ïŒ
ãã£ã¹ãããã£ã __init__ ïŒ self ïŒ
èªå·± ã create_socket ïŒ AF_INETãSOCK_STREAM ïŒ
dict ã __init__ ïŒ self ã { selfãfileno ïŒ ïŒ ïŒ self } ïŒ
èªå·± ã set_reuse_addr ïŒ ïŒ
èªå·± ã bind ïŒ ïŒãã¹ããããŒãïŒ ïŒ
èªå·± ã èã ïŒ 0xA ïŒ
èªå·± ã dataSource = PiGenerator ïŒ ïŒ
ã³ã³ã¹ãã©ã¯ã¿ãŒã§ã¯ããªããžã§ã¯ãã¯æåã«ãµãŒããŒãœã±ãããã³ãã©ãŒãšããŠåæåããã次ã«åäžã®ã¬ã³ãŒãïŒãµãŒããŒãªããžã§ã¯ããæããµãŒããŒèªäœã®ãœã±ããèšè¿°åïŒã§æ§æãããèŸæžãšããŠåæåãããŸãã èŸæžãåæåãããåã« create_socketé¢æ°ã«ãã£ãŠãœã±ãããäœæãããããšãéèŠã§ãã ãœã±ãããäœæããåã«ããã³ãã«ãååŸã§ããŸããã§ããã 次ã«ããµãŒããŒãœã±ãããæå®ããããã¹ãã®ããŒãã«ãã€ã³ããããçèŽãéå§ãããPiçªå·ãžã§ãã¬ãŒã¿ãŒãäœæãããŸããããã¯ãã¯ã©ã€ã¢ã³ããžã®ããŒã¿ã¹ããªãŒã ã®çæã«ããã«äœ¿çšãããŸãã
ãã£ã¹ããããµã€ã¯ã«ãéå§ãããåŸãäœæ¥ã®å€§éšåã¯asyncoreã¢ãžã¥ãŒã«ã«åé¡ãããŸãããã®ã¢ãžã¥ãŒã«ã¯ãæ°ããã¯ã©ã€ã¢ã³ããæ¥ç¶ããããšããµãŒããŒãªããžã§ã¯ãã®handle_acceptã¡ãœãããåŒã³åºããŠçä¿¡æ¥ç¶ãåŠçããŸãã
def handle_accept ïŒ self ïŒ ïŒ
sockã ïŒ hostãport ïŒ = self ã åãå ¥ãã ïŒ ïŒ
print 'new client fromïŒ sïŒïŒ d' ïŒ ïŒ hostãport ïŒ
stream = Stream ïŒ selfãdataSource ïŒ
èªå·± [éŽäžã fileno ïŒ ïŒ ] =ã¯ã©ã€ã¢ã³ãïŒ sockã self ãstream ïŒ
ãã³ãã©ã¡ãœããå ã§ã¯ãaccepté¢æ°ã䜿çšããŠæ°ããã¯ã©ã€ã¢ã³ããçŽæ¥åãå ¥ããããŸããaccepté¢æ°ã¯ãã¯ã©ã€ã¢ã³ãããã³æ¥ç¶ãçºçãããã¹ãããŒãã®ãã¢ãšã®éä¿¡çšã«æ°ããäœæããããœã±ãããè¿ããŸãã ãµãŒããŒã¯ãã¯ã©ã€ã¢ã³ããœã±ãããåä¿¡ãããšããžã§ãã¬ãŒã¿ãŒããããŒã¿ãèªã¿åãããã®æ°ããããŒã¿ã¹ããªãŒã ïŒStreamã¯ã©ã¹ã§å®è£ ïŒãäœæããŸãã ãã®åŸãæ°ããã¯ã©ã€ã¢ã³ããªããžã§ã¯ããã¯ã©ã€ã¢ã³ãã®ãªã¹ãã«è¿œå ãããæ°ããäœæãããããŒã¿ã¹ããªãŒã ã«ãã£ãŠåæåãããŸãã
ã¯ã©ã€ã¢ã³ãã¯ãæžã蟌ã¿å¯èœïŒïŒã¡ãœããå ã®ã¹ããªãŒã ããããŒã¿ãèªã¿åããŸãã
defæžã蟌ã¿å¯èœïŒ self ïŒ ïŒ
data = self ã¹ããªãŒã èªã ïŒ ïŒ
ããŒã¿== ãªãã® å Žå ïŒ
ãã¯ã©ã€ã¢ã³ãçµäºèªã¿åããã å°å·ã ãŸã
èªå·± ã éãã ïŒ ïŒ
åœãè¿ã
èªå·± ã ãããã¡ + =ããŒã¿
return len ïŒ selfãbuffer ïŒ > 0
æžã蟌ã¿å¯èœã¡ãœããã¯ããã£ã¹ããããµã€ã¯ã«ã®æ¬¡ã®å埩ã®åã«ãåãœã±ããã®asyncoreã¢ãžã¥ãŒã«ã«ãã£ãŠåŒã³åºããããã®ãœã±ããã®æžã蟌ã¿ã¢ã¯ã»ã¹ããã§ãã¯ããå¿ èŠããããã©ããã調ã¹ãŸãã ããã䜿çšããŠãã¹ããªãŒã ããããŒã¿ãèªã¿åãããšããã¹ããªãŒã ã«ããŒã¿ãããå Žåã¯æžã蟌ã¿ã®å¿ èŠæ§ãå ±åããŸãã ã¹ããªãŒã ãNoneãè¿ãå Žåãããã¯ãã以äžããŒã¿ããªãããœã±ãããéããããããšãæå³ããŸãã ãã®äŸã§ã¯ããã®ãããªç¶æ³ã¯çºçããŸããããªããªãã æ°ã¯ç¡éã«çæãããŸãã
ã¯ã©ã€ã¢ã³ããœã±ããã®æžã蟌ã¿æäœã®å¯çšæ§ã«ã€ããŠåŠç¿ããåŸãasyncoreã¯handle_writeïŒïŒã¡ãœãããåŒã³åºããŸãããã®ã¡ãœããã¯ã以åã«ã¹ããªãŒã ããèªã¿åã£ãããŒã¿ããœã±ããçµç±ã§éä¿¡ããŸãã
def handle_write ïŒ self ïŒ ïŒ
sent = self ã send ïŒ selfãbuffer ïŒ
èªå·± ã buffer = self ãããã¡ [éä¿¡ïŒ ]
ãžã§ãã¬ãŒã¿ãŒãšãããŒã¯å¯æ¥ã«çžäºæ¥ç¶ãããŠããã ãªãã¶ãŒããŒãã¿ãŒã³ãå®çŸããŠããŸãã ãžã§ãã¬ãŒã¿ãŒã¯ç£èŠå¯èœãªãªããžã§ã¯ããšããŠæ©èœããã€ãã³ãã®ãµãã¹ã¯ã©ã€ããšãµãã¹ã¯ã©ã€ã解é€ã®ããã«ããµãã¹ã¯ã©ã€ãã¡ãœãããšãµãã¹ã¯ã©ã€ã解é€ã¡ãœãããããããæäŸããŸãã
ã¯ã©ã¹ PiGenerator ïŒ ãªã¹ã ïŒ ïŒ
def subscribe ïŒ self ãobj ïŒ ïŒ
èªå·± ã ãã㯠ååŸ ïŒ ïŒ
è©ŠããŠãã ãã ïŒ
èªå·± ã è¿œå ïŒ obj ïŒ
self ._notify ïŒ obj = obj ïŒ
æåŸã« ïŒ
èªå·± ã ãã㯠ãªãªãŒã¹ ïŒ ïŒ
èªå·±ã§ ãªããã° ã é»å ïŒ
èªå·± ã calculator = PiCalcThread ïŒ self ãselfãlock ïŒ
èªå·± ã é»å éå§ ïŒ ïŒ
ãã®ä» ïŒ
len ïŒ self ïŒ > 0ã®å Žå ïŒ
self ._resumeCalculator ïŒ ïŒ
def unsubscribe ïŒ self ãobj ïŒ ïŒ
èªå·± ã ãã㯠ååŸ ïŒ ïŒ
èªå·± ã åé€ ïŒ obj ïŒ
èªå·± ã ãã㯠ãªãªãŒã¹ ïŒ ïŒ
len ïŒ self ïŒ < = 0ã®å Žå ïŒ
self ._pauseCalculator ïŒ ïŒ
æ°å€ã®çŽæ¥çæã¯ãåå¥ã®ã¹ã¬ããã§èšç®ãå®è¡ããåå¥ã®ã¯ã©ã¹PiCalcThreadã«ãã£ãŠå®è£ ããããããåæã¡ã«ããºã ã䜿çšããŠããµãã¹ã¯ãªãã·ã§ã³ã®è¿œå ãšåé€ã®æäœãåæããŸãã åãããããã³ã°ãªããžã§ã¯ãã䜿çšããŠããµãã¹ã¯ã©ã€ããããã¹ã¬ããããªãå Žåãã¹ã¬ããã¯äžæãããŸãã _notifyïŒïŒã¡ãœããã䜿çšããŠæ°ããã¹ããªãŒã ããµãã¹ã¯ã©ã€ããããšããããæåã«ãµãã¹ã¯ã©ã€ããããã¹ããªãŒã ã§ãªãå Žåããã®åã«èšç®ããã³ä¿åãããæ°å€ãéä¿¡ãããŸãã
_notifyïŒïŒã¡ãœããã¯çœ²åãããã¹ããªãŒã ãå®è¡ããæŽæ°ã¡ãœãããåŒã³åºããŠæ°ããæ¡ãã¹ããªãŒã ã«æž¡ããŸãã
def _notify ïŒ self ãdigits = None ãobj = None ïŒ ïŒ
objs = [ obj ] if objãŸãã¯else
digit = digits ãŸã㯠selfã§ãã æ¡
objsã®objã®å ŽåïŒ
objã æŽæ° ïŒæ°åïŒ
ã¹ããªãŒã ã®updateïŒïŒã¡ãœããã¯ãæ¢åã®ããŒã¿ã«æ°ããããŒã¿ãè¿œå ããã ãã§ãïŒ
def update ïŒ self ãdata ïŒ ïŒ
èªå·± ã ããŒã¿ + =ããŒã¿
Piæ¡çæã¹ããªãŒã ã®ã¯ã©ã¹ã¯ãPiã®æ¡ã®Unbounded Spigot Algorithm㧠Jeremy Gibbonsã«ãã£ãŠææ¡ãããã¢ã«ãŽãªãºã ã䜿çšããŸãã
ã¯ã©ã¹ PiCalcThread ïŒã¹ã¬ããïŒ ïŒ
def __init__ ïŒ self ãbufferãlock ïŒ ïŒ
ã¹ã¬ãã __init__ ïŒ self ïŒ
èªå·± ã ãããã¡ãŒ =ãããã¡ãŒ
èªå·± ã ãã㯠=ããã¯
def run ïŒ self ïŒ ïŒ
qãrãtãkãnãl = 1ã0ã1ã1ã3ã3
Trueã®å Žå ïŒ
4 * q + rt < n * tã®å ŽåïŒ
èªå·± ã ãã㯠ååŸ ïŒ ïŒ
èªå·± ã ãããã¡ newDigits ïŒ str ïŒ n ïŒ ïŒ
èªå·± ã ãã㯠ãªãªãŒã¹ ïŒ ïŒ
qãrãtãkãnãl = ïŒ 10 * qã 10 * ïŒ rn * t ïŒ ãtãkã ïŒ 10 * ïŒ 3 * q + r ïŒ ïŒ / t- 10 * nãl ïŒ
ãã®ä» ïŒ
qãrãtãkãnãl = ïŒ q * kã ïŒ 2 * q + r ïŒ * lãt * lãk + 1 ã ïŒ q * ïŒ 7 * k + 2 ïŒ + r * l ïŒ / ïŒ t * l ïŒ ãl + 2 ïŒ
æé ã ç¡ç ïŒ 0.001 ïŒ
runïŒïŒã¡ãœããã¯Piçªå·ã®æ¬¡ã®æ¡ãç¡éã«èšç®ããåã³ããã¯ã䜿çšããŠãžã§ãã¬ãŒã¿ã«å ±åãããžã§ãã¬ãŒã¿ã«ãµãã¹ã¯ã©ã€ãããŠããããŒã¿ã¹ããªãŒã ã«æž¡ããŸãã ãµãŒããŒãåäœæéãããã«å€§éã®ããŒã¿ãããŒãçæããªãããã«ã人工é 延ãè¿œå ãããŸããã
ãããªã¢ã«ã®æºåã§æ§æã匷調ããããã«ããªãœãŒã¹http://highlight.hohli.com/ã䜿çšãããŸãã ã ãã®èšäºã誰ãã«ãšã£ãŠæçšã§ããããšãæ¬åœã«é¡ã£ãŠããŸããããã®èª¬æã¯ããªã倧éã«æ£ããã£ãŠããŸãã