转自åQšhttp://www.cnblogs.com/fanzhidongyzby/p/4098546.html
æœåŠ¡å™¨ç«¯¾~–程¾lå¸¸éœ€è¦æž„é€ é«˜æ€§èƒ½çš„IO模型åQŒå¸¸è§çš„IO模型有四¿U:
åQ?åQ?/span>åŒæ¥é˜Õd¡žIOåQˆBlocking IOåQ‰ï¼šå³ä¼ ¾lŸçš„IO模型ã€?/span>
åQ?åQ?/span>åŒæ¥éžé˜»å¡?/span>IOåQˆNon-blocking IOåQ‰ï¼šé»˜è®¤åˆ›å¾çš„socket都是é˜Õd¡žçš„,éžé˜»å¡žIOè¦æ±‚socket被设¾|®äØ“NONBLOCK。注æ„这里所说的NIOòq‰™žJavaçš„NIOåQˆNew IOåQ‰åº“ã€?/span>
åQ?åQ?/span>IO多èµ\å¤ç”¨åQˆIO MultiplexingåQ‰ï¼šå³ç»å…¸çš„Reactor设计模å¼åQŒæœ‰æ—¶ä¹Ÿ¿UîCؓ异æ¥é˜Õd¡žIOåQŒJavaä¸çš„Selectorå’ŒLinuxä¸çš„epoll都是˜q™ç§æ¨¡åž‹ã€?/span>
åQ?åQ?/span>异æ¥IOåQˆAsynchronous IOåQ‰ï¼šå³ç»å…¸çš„Proactor设计模å¼åQŒä¹Ÿ¿UîCؓ异æ¥éžé˜»å¡žIOã€?/span>
åŒæ¥å’Œå¼‚æ?/span>的概忉|˜q°çš„æ˜¯ç”¨æˆïLº¿½E‹ä¸Žå†…æ ¸çš„äº¤äº’æ–¹å¼ï¼šåŒæ¥æ˜¯æŒ‡ç”¨æˆ·¾U¿ç¨‹å‘è“vIOè¯äh±‚åŽéœ€è¦ç‰å¾…æˆ–è€…è½®è¯¢å†…æ ¸IOæ“作完æˆåŽæ‰èƒ½ç‘ô¾læ‰§è¡Œï¼›è€Œå¼‚æ¥æ˜¯æŒ‡ç”¨æˆïLº¿½E‹å‘èµ·IOè¯äh±‚åŽä»¾l§ç®‹æ‰§è¡ŒåQŒå½“å†…æ ¸IOæ“作完æˆåŽä¼šé€šçŸ¥ç”¨æˆ·¾U¿ç¨‹åQŒæˆ–者调用用æˆïLº¿½E‹æ³¨å†Œçš„回调函数ã€?/span>
é˜Õd¡žå’Œéžé˜Õd¡žçš„æ¦‚忉|˜q°çš„æ˜¯ç”¨æˆïLº¿½E‹è°ƒç”¨å†…æ ¸IOæ“作的方å¼ï¼šé˜Õd¡žæ˜¯æŒ‡IOæ“作需è¦å½»åº•完æˆåŽæ‰è¿”回到用户½Iºé—´åQ›è€Œéžé˜Õd¡žæ˜¯æŒ‡IOæ“作被调用åŽç«‹å³˜q”回¾l™ç”¨æˆ·ä¸€ä¸ªçжæ€å€û|¼Œæ— 需½{‰åˆ°IOæ“作å½Õdº•完æˆã€?/span>
å¦å¤–åQ?/span>Richard Stevens 在《Unix ¾|‘络¾~–程》å·1ä¸æåˆ°çš„åŸÞZºŽä¿¡å·é©±åŠ¨çš„IOåQˆSignal Driven IOåQ‰æ¨¡åž‹ï¼Œç”׃ºŽè¯¥æ¨¡åž‹åƈä¸å¸¸ç”¨ï¼Œæœ¬æ–‡ä¸ä½œæ¶‰åŠã€‚接下æ¥åQŒæˆ‘们详¾l†åˆ†æžå››¿U常è§çš„IO模型的实现原ç†ã€‚äØ“äº†æ–¹ä¾¿æ˜qŽÍ¼Œæˆ‘们¾lŸä¸€ä½¿ç”¨IO的读æ“ä½œä½œäØ“½CÞZ¾‹ã€?/span>
一ã€?/span>åŒæ¥é˜Õd¡žIO
åŒæ¥é˜Õd¡žIO模型是最½Ž€å•çš„IO模型åQŒç”¨æˆïLº¿½E‹åœ¨å†…æ ¸˜q›è¡ŒIOæ“作时被é˜Õd¡žã€?/span>
å›?/span>1 åŒæ¥é˜Õd¡žIO
如图1所½Cºï¼Œç”¨æˆ·¾U¿ç¨‹é€šè¿‡¾pÈ»Ÿè°ƒç”¨readå‘è“vIOè¯ÀL“作,ç”Þq”¨æˆïL©ºé—´è{åˆ°å†…æ ¸ç©ºé—´ã€‚å†…æ ¸ç‰åˆ°æ•°æ®åŒ…到达åŽï¼Œç„¶åŽž®†æŽ¥æ”¶çš„æ•°æ®æ‹¯‚´åˆ°ç”¨æˆïL©ºé—ß_¼Œå®Œæˆreadæ“作ã€?/span>
用户¾U¿ç¨‹ä½¿ç”¨åŒæ¥é˜Õd¡žIOæ¨¡åž‹çš„ä¼ªä»£ç æè¿°ä¸ºï¼š
å³ç”¨æˆ·éœ€è¦ç‰å¾…readž®†socketä¸çš„æ•°æ®è¯Õd–到bufferåŽï¼Œæ‰ç‘ô¾lå¤„ç†æŽ¥æ”¶çš„æ•°æ®ã€‚整个IOè¯äh±‚的过½E‹ä¸åQŒç”¨æˆïLº¿½E‹æ˜¯è¢«é˜»å¡žçš„åQŒè¿™å¯ÆD‡´ç”¨æˆ·åœ¨å‘èµ·IOè¯äh±‚æ—Óž¼Œä¸èƒ½åšä“Q何事情,对CPU的资æºåˆ©ç”¨çއä¸å¤Ÿã€?/span>
二ã€?/span>åŒæ¥éžé˜»å¡žIO
åŒæ¥éžé˜»å¡žIOæ˜¯åœ¨åŒæ¥é˜Õd¡žIO的基¼‹€ä¸Šï¼Œž®†socket讄¡½®ä¸ºNONBLOCKã€‚è¿™æ ·åšç”¨æˆ·¾U¿ç¨‹å¯ä»¥åœ¨å‘èµ·IOè¯äh±‚åŽå¯ä»¥ç«‹åŒ™¿”回ã€?/span>
å›? åŒæ¥éžé˜»å¡žIO
如图2所½Cºï¼Œç”׃ºŽsocket是éžé˜Õd¡žçš„æ–¹å¼ï¼Œå› æ¤ç”¨æˆ·¾U¿ç¨‹å‘è“vIOè¯äh±‚时立匙¿”回。但òq¶æœªè¯Õd–åˆîC“Q何数æ®ï¼Œç”¨æˆ·¾U¿ç¨‹éœ€è¦ä¸æ–地å‘è“vIOè¯äh±‚åQŒç›´åˆ°æ•°æ®åˆ°è¾‘ÖŽåQŒæ‰çœŸæ£è¯Õd–到数æ®ï¼Œ¾l§ç®‹æ‰§è¡Œã€?/span>
用户¾U¿ç¨‹ä½¿ç”¨åŒæ¥éžé˜»å¡žIOæ¨¡åž‹çš„ä¼ªä»£ç æè¿°ä¸ºï¼š
å? 用户需è¦ä¸æ–地调用readåQŒå°è¯•读å–socketä¸çš„æ•°æ®åQŒç›´åˆ°è¯»å–æˆåŠŸåŽåQŒæ‰¾l§ç®‹å¤„ç†æŽ¥æ”¶çš„æ•°æ®ã€‚整个IOè¯äh±‚的过½E‹ä¸åQŒè™½ç„¶ç”¨æˆïLº¿½E‹æ¯‹Æ¡å‘èµ·IOè¯? 求åŽå¯ä»¥ç«‹å³˜q”回åQŒä½†æ˜¯äؓ了ç‰åˆ°æ•°æ®ï¼Œä»éœ€è¦ä¸æ–地轮询ã€é‡å¤è¯·æ±‚,消耗了大é‡çš„CPU的资æºã€‚一般很ž®‘直接ä‹É用这¿U模型,而是在其他IO模型ä¸ä‹É用éžé˜? 塞IO˜q™ä¸€ç‰ÒŽ€§ã€?/span>
三ã€?/span>IO多èµ\å¤ç”¨
IO多èµ\å¤ç”¨æ¨¡åž‹æ˜¯å¾ç«‹åœ¨å†…æ ¸æä¾›çš„多路分¼›Õd‡½æ•°select基础之上的,使用select函数å¯ä»¥é¿å…åŒæ¥éžé˜»å¡žIO模型ä¸è½®è¯¢ç‰å¾…的问题ã€?/span>
å›? 多èµ\分离函数select
如图3所½Cºï¼Œç”¨æˆ·é¦–å…ˆž®†éœ€è¦è¿›è¡ŒIOæ“作的socketæ·ÕdŠ åˆ°selectä¸ï¼Œç„¶åŽé˜Õd¡ž½{‰å¾…select¾pÈ»Ÿè°ƒç”¨˜q”回。当数æ®åˆ°è¾¾æ—Óž¼Œsocket被激‹z»ï¼Œselect函数˜q”回。用æˆïLº¿½E‹æ£å¼å‘èµ·readè¯äh±‚åQŒè¯»å–æ•°æ®åƈ¾l§ç®‹æ‰§è¡Œã€?/span>
ä»? ‹¹ç¨‹ä¸Šæ¥çœ‹ï¼Œä½¿ç”¨select函数˜q›è¡ŒIOè¯äh±‚å’ŒåŒæ¥é˜»å¡žæ¨¡åž‹æ²¡æœ‰å¤ªå¤§çš„区别åQŒç”šè‡Œ™¿˜å¤šäº†æ·ÕdŠ ç›‘è§†socketåQŒä»¥åŠè°ƒç”¨select函数的é¢å¤–æ“作,æ•? 率更差。但是,使用selectä»¥åŽæœ€å¤§çš„优势是用户å¯ä»¥åœ¨ä¸€ä¸ªçº¿½E‹å†…åŒæ—¶å¤„ç†å¤šä¸ªsocketçš„IOè¯äh±‚。用户å¯ä»¥æ³¨å†Œå¤šä¸ªsocketåQŒç„¶åŽä¸æ–地è°? 用selectè¯Õd–被激‹zÈš„socketåQŒå³å¯è¾¾åˆ°åœ¨åŒä¸€ä¸ªçº¿½E‹å†…åŒæ—¶å¤„ç†å¤šä¸ªIOè¯äh±‚的目çš?/span>ã€‚è€Œåœ¨åŒæ¥é˜Õd¡žæ¨¡åž‹ä¸ï¼Œå¿…须通过多线½E‹çš„æ–¹å¼æ‰èƒ½è¾‘Öˆ°˜q™ä¸ªç›®çš„ã€?/span>
用户¾U¿ç¨‹ä½¿ç”¨selectå‡½æ•°çš„ä¼ªä»£ç æè¿°ä¸ºï¼š
å…¶ä¸while循环å‰å°†socketæ·ÕdŠ åˆ°select监视ä¸ï¼Œç„¶åŽåœ¨while内一直调用select获å–被激‹zÈš„socketåQŒä¸€æ—¦socketå¯è¯»åQŒä¾¿è°ƒç”¨read函数ž®†socketä¸çš„æ•°æ®è¯Õd–出æ¥ã€?/span>
ç„? 而,使用selectå‡½æ•°çš„ä¼˜ç‚¹åÆˆä¸ä»…é™äºŽæ¤ã€‚虽然上˜q°æ–¹å¼å…许啾U¿ç¨‹å†…处ç†å¤šä¸ªIOè¯äh±‚åQŒä½†æ˜¯æ¯ä¸ªIOè¯äh±‚的过½E‹è¿˜æ˜¯é˜»å¡žçš„åQˆåœ¨select函数上阻 塞)åQŒåã^凿—¶é—´ç”šè‡Ïx¯”åŒæ¥é˜Õd¡žIO模型˜q˜è¦é•Ñ€‚如果用æˆïLº¿½E‹åªæ³¨å†Œè‡ªå·±æ„Ÿå…´‘£çš„socket或者IOè¯äh±‚åQŒç„¶åŽåŽ»åšè‡ªå·Þqš„事情åQŒç‰åˆ°æ•°æ®åˆ°æ¥æ—¶å†è¿›è¡Œå¤„ ç†ï¼Œåˆ™å¯ä»¥æé«˜CPU的利用率ã€?/span>
IO多èµ\å¤ç”¨æ¨¡åž‹ä½¿ç”¨äº†Reactor设计模å¼å®žçŽ°äº†è¿™ä¸€æœºåˆ¶ã€?/span>
å›? Reactor设计模å¼
å¦? å›?所½Cºï¼ŒEventHandler抽象¾c»è¡¨½CºIO事äšg处ç†å™¨ï¼Œå®ƒæ‹¥æœ‰IOæ–‡äšg奿Ÿ„HandleåQˆé€šè¿‡get_handle获å–åQ‰ï¼Œä»¥åŠå¯¹Handleçš? æ“作handle_eventåQˆè¯»/写ç‰åQ‰ã€‚ç‘ô承于EventHandlerçš„å¾cÕd¯ä»¥å¯¹äº‹äšg处ç†å™¨çš„è¡ŒäØ“˜q›è¡Œå®šåˆ¶ã€‚Reactor¾cÈ”¨äºŽç®¡ç? EventHandleråQˆæ³¨å†Œã€åˆ 除ç‰åQ‰ï¼Œòq¶ä‹É用handle_events实现事äšg循环åQŒä¸æ–è°ƒç”¨åŒæ¥äº‹ä»¶å¤šè·¯åˆ†¼›Õd™¨åQˆä¸€èˆ¬æ˜¯å†…æ ¸åQ‰çš„多èµ\分离函数 selectåQŒåªè¦æŸä¸ªæ–‡ä»¶å¥æŸ„被‹È€‹z»ï¼ˆå¯è¯»/写ç‰åQ‰ï¼Œselectž®Þp¿”回(é˜Õd¡žåQ‰ï¼Œhandle_eventsž®×ƒ¼šè°ƒç”¨ä¸Žæ–‡ä»¶å¥æŸ„å…³è”的事äšg处ç†å™¨çš„ handle_event˜q›è¡Œç›¸å…³æ“作ã€?/span>
å›?/span>5 IO多èµ\å¤ç”¨
å¦? å›?所½Cºï¼Œé€šè¿‡Reactor的方å¼ï¼Œå¯ä»¥ž®†ç”¨æˆïLº¿½E‹è½®è¯¢IOæ“作状æ€çš„工作¾lŸä¸€äº¤ç»™handle_events事äšg循环˜q›è¡Œå¤„ç†ã€‚用æˆïLº¿½E‹æ³¨å†Œäº‹ä»¶å¤„ç? 器之åŽå¯ä»¥ç‘ô¾l执行åšå…¶ä»–的工作(异æ¥åQ‰ï¼Œè€ŒReactor¾U¿ç¨‹è´Ÿè´£è°ƒç”¨å†…æ ¸çš„select函数‹‚€æŸ¥socket状æ€ã€‚当有socket被激‹zÀL—¶åQŒåˆ™é€šçŸ¥ 相应的用æˆïLº¿½E‹ï¼ˆæˆ–执行用æˆïLº¿½E‹çš„回调函数åQ‰ï¼Œæ‰§è¡Œhandle_event˜q›è¡Œæ•°æ®è¯Õd–ã€å¤„ç†çš„工作。由于select函数是阻塞的åQŒå› æ¤å¤šè·¯IOå¤ç”¨ 模型也被¿UîCؓ异æ¥é˜Õd¡žIO模型。注æ„,˜q™é‡Œçš„æ‰€è¯´çš„é˜Õd¡žæ˜¯æŒ‡select函数执行时线½E‹è¢«é˜Õd¡žåQŒè€Œä¸æ˜¯æŒ‡socket。一般在使用IO多èµ\å¤ç”¨æ¨¡åž‹ æ—Óž¼Œsocket都是讄¡½®ä¸ºNONBLOCK的,ä¸è¿‡˜q™åƈä¸ä¼šäº§ç”Ÿå½±å“åQŒå› 为用户å‘èµ·IOè¯äh±‚æ—Óž¼Œæ•°æ®å·²ç»åˆ°è¾¾äº†ï¼Œç”¨æˆ·¾U¿ç¨‹ä¸€å®šä¸ä¼šè¢«é˜Õd¡žã€?/span>
用户¾U¿ç¨‹ä½¿ç”¨IO多èµ\å¤ç”¨æ¨¡åž‹çš„ä¼ªä»£ç æè¿°ä¸ºï¼š
用户需è¦é‡å†™EventHandlerçš„handle_event函数˜q›è¡Œè¯Õd–æ•°æ®ã€å¤„ç†æ•°æ®çš„工作åQŒç”¨æˆïLº¿½E‹åªéœ€è¦å°†è‡ªå·±çš„EventHandler注册到Reactorå›_¯ã€‚Reactorä¸handle_events事äšg循环的伪代ç 大致如下ã€?/span>
事äšgå¾ªçŽ¯ä¸æ–地调用select获å–被激‹zÈš„socketåQŒç„¶åŽæ ¹æ®èŽ·å–socket对应的EventHandleråQŒæ‰§è¡Œå™¨handle_event函数å›_¯ã€?/span>
IO多èµ\å¤ç”¨æ˜¯æœ€å¸æ€‹É用的IO模型åQŒä½†æ˜¯å…¶å¼‚楽E‹åº¦˜q˜ä¸å¤?#8220;å½Õdº•”åQŒå› 为它使用了会é˜Õd¡ž¾U¿ç¨‹çš„select¾pÈ»Ÿè°ƒç”¨ã€‚å› æ¤IO多èµ\å¤ç”¨åªèƒ½¿UîCؓ异æ¥é˜Õd¡žIOåQŒè€ŒéžçœŸæ£çš„异æ¥IOã€?/span>
å››ã€?/span>异æ¥IO
“çœ? æ?#8221;的异æ¥IOéœ€è¦æ“作系¾lŸæ›´å¼ºçš„æ”¯æŒã€‚在IO多èµ\å¤ç”¨æ¨¡åž‹ä¸ï¼Œäº‹äšg循环ž®†æ–‡ä»¶å¥æŸ„的状æ€äº‹ä»‰™€šçŸ¥¾l™ç”¨æˆïLº¿½E‹ï¼Œç”Þq”¨æˆïLº¿½E‹è‡ªè¡Œè¯»å–æ•°æ®ã€å¤„ç†æ•°æ®ã€‚而在å¼? æ¥IO模型ä¸ï¼Œå½“用æˆïLº¿½E‹æ”¶åˆ°é€šçŸ¥æ—Óž¼Œæ•°æ®å·²ç»è¢«å†…æ ¸è¯»å–完毕,òq¶æ”¾åœ¨äº†ç”¨æˆ·¾U¿ç¨‹æŒ‡å®šçš„ç¼“å†²åŒºå†…ï¼Œå†…æ ¸åœ¨IO完æˆåŽé€šçŸ¥ç”¨æˆ·¾U¿ç¨‹ç›´æŽ¥ä½¿ç”¨å›_¯ã€?/span>
异æ¥IO模型使用了Proactor设计模å¼å®žçŽ°äº†è¿™ä¸€æœºåˆ¶ã€?/span>
å›? Proactor设计模å¼
å¦? å›?åQŒProactor模å¼å’ŒReactor模å¼åœ¨ç»“æž„ä¸Šæ¯”è¾ƒç›æ€¼¼åQŒä¸˜q‡åœ¨ç”¨æˆ·åQˆClientåQ‰ä‹É用方å¼ä¸Šå·®åˆ«è¾ƒå¤§ã€‚Reactor模å¼ä¸ï¼Œç”¨æˆ·¾U¿ç¨‹é€šè¿‡ å‘Reactor对象注册感兴‘£çš„事äšg监å¬åQŒç„¶åŽäº‹ä»¶è§¦å‘时调用事äšg处ç†å‡½æ•°ã€‚而Proactor模å¼ä¸ï¼Œç”¨æˆ·¾U¿ç¨‹ž®? AsynchronousOperationåQˆè¯»/写ç‰åQ‰ã€Proactorä»¥åŠæ“ä½œå®Œæˆæ—¶çš„CompletionHandler注册åˆ? AsynchronousOperationProcessor。AsynchronousOperationProcessor使用Facadeæ¨¡å¼æ? 供了一¾l„å¼‚æ¥æ“作APIåQˆè¯»/写ç‰åQ‰ä¾›ç”¨æˆ·ä½¿ç”¨åQŒå½“用户¾U¿ç¨‹è°ƒç”¨å¼‚æ¥APIåŽï¼Œä¾¿ç‘ô¾l执行自å·Þqš„ä»ÕdŠ¡ã€? AsynchronousOperationProcessor 会开å¯ç‹¬ç«‹çš„å†…æ ¸¾U¿ç¨‹æ‰§è¡Œå¼‚æ¥æ“作åQŒå®žçŽ°çœŸæ£çš„异æ¥ã€‚当异æ¥IOæ“ä½œå®Œæˆ æ—Óž¼ŒAsynchronousOperationProcessorž®†ç”¨æˆïLº¿½E‹ä¸ŽAsynchronousOperation一èµäh³¨å†Œçš„Proactor å’ŒCompletionHandlerå–出åQŒç„¶åŽå°†CompletionHandler与IOæ“作的结果数æ®ä¸€èµ¯‚{å‘ç»™ ProactoråQŒProactor负责回调æ¯ä¸€ä¸ªå¼‚æ¥æ“作的事äšg完æˆå¤„ç†å‡½æ•°handle_event。虽然Proactor模å¼ä¸æ¯ä¸ªå¼‚æ¥æ“作都å¯ä»¥ ¾l‘定一个Proactor对象åQŒä½†æ˜¯ä¸€èˆ¬åœ¨æ“作¾pÈ»Ÿä¸ï¼ŒProactor被实çŽîCØ“Singleton模å¼åQŒä»¥ä¾¿äºŽé›†ä¸åŒ–åˆ†å‘æ“作完æˆäº‹ä»¶ã€?/span>
å›?/span>7 异æ¥IO
å¦? å›?所½Cºï¼Œå¼‚æ¥IO模型ä¸ï¼Œç”¨æˆ·¾U¿ç¨‹ç›´æŽ¥ä½¿ç”¨å†…æ ¸æä¾›çš„异æ¥IO APIå‘è“vreadè¯äh±‚åQŒä¸”å‘è“våŽç«‹åŒ™¿”回,¾l§ç®‹æ‰§è¡Œç”¨æˆ·¾U¿ç¨‹ä»£ç 。丘q‡æ¤æ—¶ç”¨æˆïLº¿½E‹å·² ¾l将调用的AsynchronousOperationå’ŒCompletionHandleræ³¨å†Œåˆ°å†…æ ¸ï¼Œç„¶åŽæ“作¾pÈ»Ÿå¼€å¯ç‹¬ç«‹çš„å†…æ ¸¾U¿ç¨‹åŽÕd¤„ç†IOæ“? 作。当readè¯äh±‚的数æ®åˆ°è¾¾æ—¶åQŒç”±å†…æ ¸è´Ÿè´£è¯Õd–socketä¸çš„æ•°æ®åQŒåƈ写入用户指定的缓冲区ä¸ã€‚最åŽå†…æ ¸å°†read的数æ®å’Œç”¨æˆ·¾U¿ç¨‹æ³¨å†Œçš? CompletionHandler分呾l™å†…部ProactoråQŒProactorž®†IO完æˆçš„ä¿¡æ¯é€šçŸ¥¾l™ç”¨æˆïLº¿½E‹ï¼ˆä¸€èˆ¬é€šè¿‡è°ƒç”¨ç”¨æˆ·¾U¿ç¨‹æ³¨å†Œçš„完æˆäº‹ä»? 处ç†å‡½æ•°åQ‰ï¼Œå®Œæˆå¼‚æ¥IOã€?/span>
用户¾U¿ç¨‹ä½¿ç”¨å¼‚æ¥IOæ¨¡åž‹çš„ä¼ªä»£ç æè¿°ä¸ºï¼š
用户需è¦é‡å†™CompletionHandlerçš„handle_event函数˜q›è¡Œå¤„ç†æ•°æ®çš„å·¥ä½œï¼Œå‚æ•°buffer表示Proactorå·²ç»å‡†å¤‡å¥½çš„æ•°æ®åQŒç”¨æˆïLº¿½E‹ç›´æŽ¥è°ƒç”¨å†…æ ¸æä¾›çš„异æ¥IO APIåQŒåƈž®†é‡å†™çš„CompletionHandler注册å›_¯ã€?/span>
ç›? 比于IO多èµ\å¤ç”¨æ¨¡åž‹åQŒå¼‚æ¥IOòq¶ä¸å分常用åQŒä¸ž®‘高性能òq¶å‘æœåŠ¡½E‹åºä½¿ç”¨IO多èµ\å¤ç”¨æ¨¡åž‹+多线½E‹ä“Q务处ç†çš„æž¶æž„基本å¯ä»¥æ»¡èƒöéœ€æ±‚ã€‚å†µä¸”ç›®å‰æ“作系¾lŸå¯¹ 异æ¥IO的支æŒåƈéžç‰¹åˆ«å®Œå–„,更多的是采用IO多èµ\å¤ç”¨æ¨¡åž‹æ¨¡æ‹Ÿå¼‚æ¥IO的方å¼ï¼ˆIO事äšgè§¦å‘æ—¶ä¸ç›´æŽ¥é€šçŸ¥ç”¨æˆ·¾U¿ç¨‹åQŒè€Œæ˜¯ž®†æ•°æ®è¯»å†™å®Œæ¯•åŽæ”‘Öˆ°ç”¨æˆ·æŒ‡å®šçš? ¾~“冲åŒÞZ¸åQ‰ã€‚Java7之åŽå·²ç»æ”¯æŒäº†å¼‚æ¥IOåQŒæ„Ÿå…´è¶£çš„读者å¯ä»¥å°è¯•ä‹É用ã€?/span>
本文从基本概å¿üc€å·¥ä½œæµ½E‹å’Œä»£ç ½C? 例三个层‹Æ¡ç®€è¦æ˜qîCº†å¸¸è§çš„å››¿U高性能IO模型的结构和原ç†åQŒç†æ¸…äº†åŒæ¥ã€å¼‚æ¥ã€é˜»å¡žã€éžé˜Õd¡ž˜q™äº›å®ÒŽ˜“æ·äh·†çš„æ¦‚å¿üc€‚通过寚w«˜æ€§èƒ½IO模型的ç†è§£ï¼Œå¯ä»¥åœ¨æœ 务端½E‹åºçš„å¼€å‘ä¸é€‰æ‹©æ›´ç¬¦åˆå®žé™…业务特点的IO模型åQŒæé«˜æœåŠ¡è´¨é‡ã€‚å¸Œæœ›æœ¬æ–‡å¯¹ä½ æœ‰æ‰€å¸®åŠ©ã€?/span>
ç›æ€¼¼çš„:
http://www.cnblogs.com/nufangrensheng/p/3588690.html
http://www.ibm.com/developerworks/cn/linux/l-async/
Python没有内å¾ä¸€ä¸ªç¼–è¯‘äØ“exe的功能。给python½E‹åºçš„部¾|²å¸¦æ¥ä¸ž®‘çš„éºÈƒ¦ã€?
所以就会出çŽîC¸€äº›py2exe之类的很ä¸é”™çš„工典P¼Œç”¨äºŽè‡ªåЍæŠ?pyæ–‡äšg¾~–译ä¸?exeæ–‡äšgã€?
最˜q‘抽½Iºç ”½I¶äº†ä¸€ä¸‹æ‰‹åŠ¨å®žçŽ°ç±»ä¼¼py2exeçš„åŠŸèƒ½ï¼Œå¸Œæœ›åŠ å¼ºå¯¹python的了解ã€?
¾l“æžœ˜q˜ç›¸å½“ä¸é”™ã€‚把¾l“果记录下æ¥åQŒä¸Žå¤§å®¶å…׃ínã€?
æ–‡ä¸æ‰€æè¿°çš„æ–¹æ³•,åŸÞZºŽpythonçš„ä»¥ä¸‹å‡ ä¸ªåŠŸèƒ?
1. python½E‹åº˜q行æ—Óž¼Œä¼šåœ¨sys.path指定的èµ\径䏿Ÿ¥æ‰¾åº“文件ã€?
2. pythonä»?.3开始,支æŒä»Žzipæ–‡äšgä¸importåº?支æŒ.py,.pycå’?pyoåQŒä½†ä¸æ”¯æŒ?pyd)
3. pythonæä¾›C APIåQŒè®©cè¯è¨€çš„程åºï¼Œå¯ä»¥å¾ˆæ–¹ä¾¿çš„调用python的程åº?
注:å‡è®¾python安装在c:\python25目录ä¸ï¼Œæœ€åŽçš„坿‰§è¡Œæ–‡ä»¶æ”¾åˆ°d:\dist目录ä¸?/strong>
1. 先去c:\python25\Lib目录åQŒæŠŠæ‰€æœ‰æ–‡ä»‰™ƒ½å¤åˆ¶å‡ºæ¥åQŒæ¯”如å¤åˆ¶åˆ°d:\pythonlib目录ä¸?
2. 开一个cmd½H—å£åQŒè¿›å…¥d:\pythonlib目录ä¸ï¼Œ˜q行 python -OO compileall.py -f . 把libä¸çš„.pyæ–‡äšg都编译æˆ.pyoæ–‡äšg
3. åˆ é™¤d:\pythonlibç›®å½•ä¸æ‰€æœ‰çš„.pyå’?pycæ–‡äšgåQŒå› 为我们åªè¦æœ‰.pyoæ–‡äšgž®±å¯ä»¥è®©˜q™äº›åº“è¿è¡Œäº†ã€?
4. åˆ é™¤ç›®å½•ä¸æ‰€æœ‰ç”¨ä¸ç€çš„æ–‡ä»Óž¼Œæ¯”如cursesåQŒteståQŒidlelibåQŒmsilib½{‰ï¼Œä»¥å‡ž®‘ç”Ÿæˆæ–‡ä»¶çš„体积ã€?
5. 把这些库打包æˆä¸€ä¸ªzipæ–‡äšgåQŒæ¯”如stdlib.zipåQŒæ”¾åˆ°d:\dist目录ä¸?
6. 把c:\python25\dlls目录ä¸çš„.pydå’?dllæ–‡äšgåQŒå¤åˆ¶åˆ°d:\dist\dlls目录ä¸ï¼Œå½“ç„¶åQŒåˆ 除ä¸å¯èƒ½ç”¨åˆ°çš„一些文件_msi.pyd,_ssl.pyd½{‰ç‰åQŒå¯ä»¥å‡ž®‘文件的体积
7. 把自己写的程åºï¼Œä¹ŸæŒ‰æ¥éª¤2è‡Ïx¥éª?所说的æ–ÒŽ³•åQŒæ‰“æˆä¸€ä¸ªmysrc.zip包,攑ֈ°d:\dist目录ä¸ã€?注æ„åQšè‡ªå·±å†™çš„程åºçš„å…¥å£åº”该是main.pyoæ–‡äšg
8. 用以下C½E‹åº¾~–译å‡ÞZ¸€ä¸ªå¯æ‰§è¡Œæ–‡äšgåQŒæ¯”方说å«runpy.exeåQŒä¹Ÿæ”‘Öˆ°d:\distä¸ã€?
9. 把python25.dll攑ֈ°d:\dist目录ä¸ã€?
˜q™æ ·æ¥ï¼Œd:\dist目录ä¸ï¼Œä¸€å…±åªæœ?ä¸ªæ–‡ä»¶åŠ ä¸€ä¸ªç›®å½•ï¼š
dlls目录åQšç”¨äºŽå˜æ”¾æ‰€æœ‰çš„dllæ–‡äšgå’Œpydæ–‡äšg
stdlib.zipæ–‡äšgåQšç”¨äºŽå˜æ”¾æ‰€æœ‰çš„pythonçš?pyoæ–‡äšgæ ¼å¼çš„æ ‡å‡†åº“
mysrc.zipæ–‡äšgåQšç”¨äºŽå˜æ”¾è‡ªå·±å†™çš„程åºã€‚注æ„,自己写的½E‹åºçš„å…¥å£åœ¨main.pyoä¸ã€?
runpy.exeæ–‡äšgåQšç¨‹åºçš„å¯åŠ¨æ–‡äšgåQŒå¯åЍåŽä¼šè®¾å®špythonçš„sys.pathåQŒç„¶åŽè°ƒç”¨main模å—
python25.dllæ–‡äšgåQšpythonçš„æ ¸å¿ƒdllåQŒrunpy.exeä¾èµ–于这个dll
注:当然åQŒè¿™¿U打包方å¼ç¬¬ä¸€‹Æ¡åšçš„æ—¶å€™æ¯”较麻烦,但之åŽå°±å¯ä»¥åªè¦æŠŠè‡ªå·Þqš„½E‹åºæ‰“包ž®±å¥½äº†ï¼Œå…¶å®ƒçš„ä¸ç”¨å˜ã€?
而且åQŒå¦‚果自å·Þqš„½E‹åº¾lå¸¸åšæ”¹åŠ¨çš„è¯ï¼Œè‡ªå·±çš„程åºä¹Ÿå¯ä»¥ä¸æ‰“包,直接攑ֈ°d:\distä¸ï¼Œåæ£runpy.exeå¯åЍ½E‹åºçš„æ—¶å€™ï¼Œåªè¦èƒ½æ£å¸¸è¿è¡Œimport mainž®±å¯ä»¥äº†ã€?
有丞®‘äh写email¾l™æˆ‘åQŒé—®æˆ‘è¦æˆ‘åšçš„包。大家å¯ä»¥åœ¨˜q™é‡Œä¸‹è²åŸÞZºŽ2.5.2版本的包åQ?python_dist.7z 以åŠåŸÞZºŽ3.1.2版本的包åQ?python31-dist.7z
注:3.1.2ä¾èµ–äº?a class="http" >visual c++ 2008 redistributable package. å¦‚æžœåœ¨ç›®æ ‡æœºå™¨ä¸Šæ²¡æœ‰å®‰è£…åQŒåˆ™½E‹åº˜q行ä¸è“væ¥ã€?
解开包åŽåQŒåªè¦ç”¨è‡ªå·±çš„ç¨‹åºæ›¿æ¢mysrc.zipž®±å¯ä»¥ä‹É用了ã€?
包里有runpy.exeå’Œrunpyw.exe两个文äšg。其ä¸ï¼Œrunpy.exe是控制尽E‹åºåQŒrunpyw.exeæ˜¯éžæŽ§åˆ¶å°ç¨‹åºã€‚这两个½E‹åºåˆ†åˆ«¾cÖM¼¼äºŽpython.exeå’Œpythonw.exe。想让程åºè¿è¡Œæ—¶å‡ºçŽ°ä¸€ä¸ªæŽ§åˆ¶å°åQŒå°±˜q行runpy.exeåQŒå¦‚æžœä¸æƒ›_‡ºçŽ°é»‘é»‘çš„æŽ§åˆ¶åŽÍ¼Œž®Þp¿è¡Œrunpyw.exeã€?