±à¼ÍƼö: |
±¾ÎÄÀ´Ô´pythonÉçÇø£¬±¾ÎÄÌÖÂ۵ı³¾°ÊÇLinux»·¾³ÏµÄnetwork
IO,ÒÔ¼°,ʼþÇý¶¯ÐͳÌÐòÄ£Ð͵ÄÁ÷³Ì£¬Ï£Íû¶ÔÄúµÄѧϰÓÐËù°ïÖú¡£ |
|
Ò»¡¢Ê¼þÇý¶¯Ä£ÐͽéÉÜ
1¡¢´«Í³µÄ±à³Ìģʽ
ÀýÈ磺ÏßÐÔģʽ´óÖÂÁ÷³Ì
¿ªÊ¼--->´úÂë¿éA--->´úÂë¿éB--->´úÂë¿éC--->´úÂë¿éD--->......--->½áÊø
ÿһ¸ö´úÂë¿éÀïÊÇÍê³É¸÷ÖÖ¸÷ÑùÊÂÇéµÄ´úÂ룬µ«±à³ÌÕßÖªµÀ´úÂë¿éA,B,C,D...µÄÖ´ÐÐ˳Ðò£¬Î¨Ò»Äܹ»¸Ä±äÕâ¸öÁ÷³ÌµÄÊÇÊý¾Ý¡£ÊäÈ벻ͬµÄÊý¾Ý£¬¸ù¾ÝÌõ¼þÓï¾äÅжϣ¬Á÷³Ì»òÐí¾Í¸ÄΪA--->C--->E...--->½áÊø¡£Ã¿Ò»´Î³ÌÐòÔËÐÐ˳Ðò»òÐí¶¼²»Í¬£¬µ«ËüµÄ¿ØÖÆÁ÷³ÌÊÇÓÉÊäÈëÊý¾ÝºÍÄã±àдµÄ³ÌÐò¾ö¶¨µÄ¡£Èç¹ûÄãÖªµÀÕâ¸ö³ÌÐòµ±Ç°µÄÔËÐÐ״̬£¨°üÀ¨ÊäÈëÊý¾ÝºÍ³ÌÐò±¾Éí£©£¬ÄÇÄã¾ÍÖªµÀ½ÓÏÂÀ´ÉõÖÁÒ»Ö±µ½½áÊøËüµÄÔËÐÐÁ÷³Ì¡£
ÀýÈ磺ʼþÇý¶¯ÐͳÌÐòÄ£ÐÍ´óÖÂÁ÷³Ì
¿ªÊ¼--->³õʼ»¯--->µÈ´ý
ÓëÉÏÃæ´«Í³±à³Ìģʽ²»Í¬£¬Ê¼þÇý¶¯³ÌÐòÔÚÆô¶¯Ö®ºó£¬¾ÍÔÚÄǵȴý£¬µÈ´ýÊ²Ã´ÄØ£¿µÈ´ý±»Ê¼þ´¥·¢¡£´«Í³±à³ÌÏÂÒ²ÓС°µÈ´ý¡±µÄʱºò£¬±ÈÈçÔÚ´úÂë¿éDÖУ¬Ä㶨ÒåÁËÒ»¸öinput()£¬ÐèÒªÓû§ÊäÈëÊý¾Ý¡£µ«ÕâÓëÏÂÃæµÄµÈ´ý²»Í¬£¬´«Í³±à³ÌµÄ¡°µÈ´ý¡±£¬±ÈÈçinput()£¬Äã×÷Ϊ³ÌÐò±àдÕßÊÇÖªµÀ»òÕßÇ¿ÖÆÓû§ÊäÈëij¸ö¶«Î÷µÄ£¬»òÐíÊÇÊý×Ö£¬»òÐíÊÇÎļþÃû³Æ£¬Èç¹ûÓû§ÊäÈë´íÎó£¬Ä㻹ÐèÒªÌáÐÑËû£¬²¢ÇëËûÖØÐÂÊäÈ롣ʼþÇý¶¯³ÌÐòµÄµÈ´ýÔòÊÇÍêÈ«²»ÖªµÀ£¬Ò²²»Ç¿ÖÆÓû§ÊäÈë»òÕ߸Éʲô¡£Ö»ÒªÄ³Ò»Ê¼þ·¢Éú£¬ÄdzÌÐò¾Í»á×ö³öÏàÓ¦µÄ¡°·´Ó¦¡±¡£ÕâЩʼþ°üÀ¨£ºÊäÈëÐÅÏ¢¡¢Êó±ê¡¢Çû÷¼üÅÌÉÏij¸ö¼ü»¹ÓÐϵͳÄÚ²¿¶¨Ê±Æ÷´¥·¢¡£
2¡¢Ê¼þÇý¶¯Ä£ÐÍ
ͨ³££¬ÎÒÃÇд·þÎñÆ÷´¦ÀíÄ£Ð͵ijÌÐòʱ£¬ÓÐÒÔϼ¸ÖÖÄ£ÐÍ£º
£¨1£©Ã¿ÊÕµ½Ò»¸öÇëÇ󣬴´½¨Ò»¸öеĽø³Ì£¬À´´¦Àí¸ÃÇëÇó£»
£¨2£©Ã¿ÊÕµ½Ò»¸öÇëÇ󣬴´½¨Ò»¸öеÄỊ̈߳¬À´´¦Àí¸ÃÇëÇó£»
£¨3£©Ã¿ÊÕµ½Ò»¸öÇëÇ󣬷ÅÈëÒ»¸öʼþÁÐ±í£¬ÈÃÖ÷½ø³Ìͨ¹ý·Ç×èÈûI/O·½Ê½À´´¦ÀíÇëÇó
3¡¢µÚÈýÖÖ¾ÍÊÇг̡¢Ê¼þÇý¶¯µÄ·½Ê½£¬Ò»°ãÆÕ±éÈÏΪµÚ£¨3£©ÖÖ·½Ê½ÊÇ´ó¶àÊýÍøÂç·þÎñÆ÷²ÉÓõķ½Ê½
ʾÀý£º
1
#ʼþÇý¶¯Ö®Êó±êµã»÷ʼþ×¢²á
2
3 <!DOCTYPE html>
4 <html lang="en">
5 <head>
6 <meta charset="UTF-8">
7 <title>Title</title>
8
9 </head>
10 <body>
11
12 <p onclick="fun()">µãÎÒѽ</p>
13
14
15 <script type="text/javascript">
16 function fun() {
17 alert('Ô¼Âð?')
18 }
19 </script>
20 </body>
21
22 </html> |
Ö´Ðнá¹û£º

ÔÚUI±à³ÌÖУ¬³£³£Òª¶ÔÊó±êµã»÷½øÐÐÏàÓ¦£¬Ê×ÏÈÈçºÎ»ñµÃÊó±êµã»÷ÄØ£¿
Á½ÖÖ·½Ê½£º
1¡¢´´½¨Ò»¸öÏß³ÌÑ»·¼ì²âÊÇ·ñÓÐÊó±êµã»÷
ÄÇôÕâ¸ö·½Ê½ÓÐÒÔϼ¸¸öȱµã£º
CPU×ÊÔ´ÀË·Ñ£¬¿ÉÄÜÊó±êµã»÷µÄƵÂʷdz£Ð¡£¬µ«ÊÇɨÃèÏ̻߳¹ÊÇ»áһֱѻ·¼ì²â£¬Õâ»áÔì³ÉºÜ¶àµÄCPU×ÊÔ´ÀË·Ñ£»Èç¹ûɨÃèÊó±êµã»÷µÄ½Ó¿ÚÊÇ×èÈûµÄÄØ£¿
Èç¹ûÊǶÂÈûµÄ£¬ÓÖ»á³öÏÖÏÂÃæÕâÑùµÄÎÊÌ⣬Èç¹ûÎÒÃDz»µ«ÒªÉ¨ÃèÊó±êµã»÷£¬»¹ÒªÉ¨Ãè¼üÅÌÊÇ·ñ°´Ï£¬ÓÉÓÚɨÃèÊó±êʱ±»¶ÂÈûÁË£¬ÄÇô¿ÉÄÜÓÀÔ¶²»»áȥɨÃè¼üÅÌ£»
Èç¹ûÒ»¸öÑ»·ÐèҪɨÃèµÄÉ豸·Ç³£¶à£¬ÕâÓÖ»áÒýÀ´ÏìӦʱ¼äµÄÎÊÌ⣻
ËùÒÔ£¬¸Ã·½Ê½ÊǷdz£²»ºÃµÄ¡£
2¡¢Ê¼þÇý¶¯Ä£ÐÍ
Ŀǰ´ó²¿·ÖµÄUI±à³Ì¶¼ÊÇʼþÇý¶¯Ä£ÐÍ£¬ÈçºÜ¶àUIƽ̨¶¼»áÌṩonClick()ʼþ£¬Õâ¸öʼþ¾Í´ú±íÊó±ê°´ÏÂʼþ¡£Ê¼þÇý¶¯Ä£ÐÍ´óÌå˼·ÈçÏ£º
1.ÓÐÒ»¸öʼþ£¨ÏûÏ¢£©¶ÓÁУ»
2.Êó±ê°´ÏÂʱ£¬ÍùÕâ¸ö¶ÓÁÐÖÐÔö¼ÓÒ»¸öµã»÷ʼþ£¨ÏûÏ¢£©£»
3.ÓиöÑ»·£¬²»¶Ï´Ó¶ÓÁÐÈ¡³öʼþ£¬¸ù¾Ý²»Í¬µÄʼþ£¬µ÷Óò»Í¬µÄº¯Êý£¬ÈçonClick()¡¢onKeyDown()µÈ£»
4.ʼþ£¨ÏûÏ¢£©Ò»°ã¶¼¸÷×Ô±£´æ¸÷×ԵĴ¦Àíº¯ÊýÖ¸Õ룬ÕâÑù£¬Ã¿¸öÏûÏ¢¶¼ÓжÀÁ¢µÄ´¦Àíº¯Êý£»
ʲôÊÇʼþÇý¶¯Ä£ÐÍ £¿
Ŀǰ´ó²¿·ÖµÄUI±à³Ì¶¼ÊÇʼþÇý¶¯Ä£ÐÍ£¬ÈçºÜ¶àUIƽ̨¶¼»áÌṩonClick()ʼþ£¬Õâ¸öʼþ¾Í´ú±íÊó±ê°´ÏÂʼþ¡£Ê¼þÇý¶¯Ä£ÐÍ´óÌå˼·ÈçÏ£º
1.ÓÐÒ»¸öʼþ£¨ÏûÏ¢£©¶ÓÁУ»
2.Êó±ê°´ÏÂʱ£¬ÍùÕâ¸ö¶ÓÁÐÖÐÔö¼ÓÒ»¸öµã»÷ʼþ£¨ÏûÏ¢£©£»
3.ÓиöÑ»·£¬²»¶Ï´Ó¶ÓÁÐÈ¡³öʼþ£¬¸ù¾Ý²»Í¬µÄʼþ£¬µ÷Óò»Í¬µÄº¯Êý£¬ÈçonClick()¡¢onKeyDown()µÈ£»
4.ʼþ£¨ÏûÏ¢£©Ò»°ã¶¼¸÷×Ô±£´æ¸÷×ԵĴ¦Àíº¯ÊýÖ¸Õ룬ÕâÑù£¬Ã¿¸öÏûÏ¢¶¼ÓжÀÁ¢µÄ´¦Àíº¯Êý£»

ʼþÇý¶¯±à³ÌÊÇÒ»ÖÖ±à³Ì·¶Ê½£¬ÕâÀï³ÌÐòµÄÖ´ÐÐÁ÷ÓÉÍⲿʼþÀ´¾ö¶¨¡£ËüµÄÌØµãÊǰüº¬Ò»¸öʼþÑ»·£¬µ±Íⲿʼþ·¢ÉúʱʹÓûص÷»úÖÆÀ´´¥·¢ÏàÓ¦µÄ´¦Àí¡£ÁíÍâÁ½ÖÖ³£¼ûµÄ±à³Ì·¶Ê½ÊÇ£¨µ¥Ị̈߳©Í¬²½ÒÔ¼°¶àÏ̱߳à³Ì¡£
ÐèÖª£ºÃ¿¸öcpu¶¼ÓÐÆäÒ»Ì׿ÉÖ´ÐеÄרÃÅÖ¸Á£¬ÈçSPARCºÍPentium£¬Æäʵÿ¸öÓ²¼þÖ®É϶¼ÒªÓÐÒ»¸ö¿ØÖƳÌÐò£¬cpuµÄÖ¸Á¾ÍÊÇcpuµÄ¿ØÖƳÌÐò¡£
¶þ¡¢IOÄ£ÐÍ×¼±¸
ÔÚ½øÐнâÊÍ֮ǰ£¬Ê×ÏÈҪ˵Ã÷¼¸¸ö¸ÅÄ
1.Óû§¿Õ¼äºÍÄں˿ռä
2.½ø³ÌÇл»
3.½ø³ÌµÄ×èÈû
4.ÎļþÃèÊö·û
5.»º´æ I/O
1¡¢Óû§¿Õ¼äºÍÄں˿ռä
ÀýÈ磺²ÉÓÃÐéÄâ´æ´¢Æ÷£¬¶ÔÓÚ32bit²Ù×÷ϵͳ£¬ËüµÄѰַ¿Õ¼ä(ÐéÄâ´æ´¢¿Õ¼äΪ4G£¬¼´2µÄ32´Î·½)¡£
²Ù×÷ϵͳµÄºËÐÄÊÇÄںˣ¬¶ÀÁ¢ÓÚÆÕͨµÄÓ¦ÓóÌÐò£¬¿ÉÒÔ·ÃÎÊÊܱ£»¤µÄÄÚ´æ¿Õ¼ä£¬Ò²¿ÉÒÔ·ÃÎʵײãÓ²¼þµÄËùÓÐȨÏÞ¡£
ΪÁ˱£Ö¤Óû§½ø³Ì²»ÄÜÖ±½Ó²Ù×÷ÄÚºË(kernel),±£Ö¤Äں˵ݲȫ£¬²Ù×÷ϵͳ½«ÐéÄâ¿Õ¼ä»®·ÖΪÁ½²¿·Ö£ºÒ»²¿·ÖΪÄں˿ռ䣬ÁíÒ»²¿·ÖΪÓû§¿Õ¼ä¡£
ÄÇô²Ù×÷ϵͳÊÇÈçºÎ·ÖÅä¿Õ¼äµÄ£¿ÕâÀï¾Í»áÉæ¼°µ½ÄÚºË̬ºÍÓû§Ì¬µÄÁ½ÖÖ¹¤×÷״̬¡£
1G£º 0 --->ÄÚºË̬
3G£º 1 --->Óû§Ì¬
CPUµÄÖ¸Á£¬ÊÇͨ¹ý0ºÍ1 ¾ö¶¨ÄãÊÇÓû§Ì¬£¬»¹ÊÇÄÚºË̬

¼ÆËã»úµÄÁ½ÖÖ¹¤×÷״̬: ÄÚºË̬ºÍÓû§Ì¬
cpuµÄÁ½ÖÖ¹¤×÷״̬£º
ÏÖÔڵIJÙ×÷ϵͳ¶¼ÊÇ·Öʱ²Ù×÷ϵͳ£¬·ÖʱµÄ¸ùÔ´£¬À´×ÔÓÚÓ²¼þ²ãÃæ²Ù×÷ϵͳÄÚºËÕ¼ÓõÄÄÚ´æÓëÓ¦ÓóÌÐòÕ¼ÓõÄÄÚ´æ±Ë´ËÖ®¼ä¸ôÀë¡£cpuͨ¹ýpsw£¨³ÌÐò״̬¼Ä´æÆ÷£©ÖеÄÒ»¸ö2½øÖÆÎ»À´¿ØÖÆcpu±¾ÉíµÄ¹¤×÷״̬£¬¼´ÄÚºË̬ÓëÓû§Ì¬¡£
ÄÚºË̬£º²Ù×÷ϵͳÄÚºËÖ»ÄÜÔË×÷ÓÚcpuµÄÄÚºË̬£¬ÕâÖÖ״̬Òâζ×Å¿ÉÒÔÖ´ÐÐcpuËùÓеÄÖ¸Á¿ÉÒÔÖ´ÐÐcpuËùÓеÄÖ¸ÁÕâÒ²Òâζ×ŶԼÆËã»úÓ²¼þ×ÊÔ´ÓÐ×ÅÍêÈ«µÄ¿ØÖÆÈ¨ÏÞ£¬²¢ÇÒ¿ÉÒÔ¿ØÖÆcpu¹¤×÷״̬ÓÉÄÚºË̬ת³ÉÓû§Ì¬¡£
Óû§Ì¬£ºÓ¦ÓóÌÐòÖ»ÄÜÔË×÷ÓÚcpuµÄÓû§Ì¬£¬ÕâÖÖ״̬Òâζ×ÅÖ»ÄÜÖ´ÐÐcpuËùÓеÄÖ¸ÁîµÄһС²¿·Ö£¨»òÕß³ÆÎªËùÓÐÖ¸ÁîµÄÒ»¸ö×Ó¼¯£©£¬ÕâһС²¿·ÖÖ¸Áî¶Ô¼ÆËã»úµÄÓ²¼þ×ÊԴûÓзÃÎÊȨÏÞ£¨±ÈÈçI/O£©£¬²¢ÇÒ²»ÄÜ¿ØÖÆÓÉÓû§Ì¬×ª³ÉÄÚºË̬¡£
2¡¢½ø³ÌÇл»
ΪÁË¿ØÖƽø³ÌµÄÖ´ÐУ¬Äں˱ØÐëÓÐÄÜÁ¦¹ÒÆðÕýÔÚCPUÉÏÖ´ÐеĽø³Ì£¬²¢»Ö¸´ÒÔǰ¹ÒÆðµÄij¸ö½ø³ÌµÄÖ´ÐУ¬ÕâÖÖÐÐΪ¾Í±»³ÆÎª½ø³ÌÇл»¡£
×ܽ᣺½ø³ÌÇл»ÊǺÜÏûºÄ×ÊÔ´µÄ¡£
3¡¢½ø³ÌµÄ×èÈû
ÕýÔÚÖ´ÐеĽø³Ì£¬ÓÉÓÚÆÚ´ýµÄijЩʼþδ·¢Éú£¬ÈçÇëÇóϵͳ×ÊԴʧ°Ü¡¢µÈ´ýijÖÖ²Ù×÷µÄÍê³É¡¢ÐÂÊý¾ÝÉÐδµ½´ï»òÎÞй¤×÷×öµÈ£¬ÔòÓÉϵͳ×Ô¶¯Ö´ÐÐ×èÈûÔÓï(Block)£¬Ê¹×Ô¼ºÓÉÔËÐÐ״̬±äΪ×èÈû״̬¡£¿É¼û£¬½ø³ÌµÄ×èÈûÊǽø³Ì×ÔÉíµÄÒ»ÖÖÖ÷¶¯ÐÐΪ£¬Ò²Òò´ËÖ»Óд¦ÓÚÔËÐÐ̬µÄ½ø³Ì£¨»ñµÃCPU£©£¬²Å¿ÉÄܽ«ÆäתΪ×èÈû״̬¡£µ±½ø³Ì½øÈë×èÈû״̬£¬ÊDz»Õ¼ÓÃCPU×ÊÔ´µÄ¡£
4¡¢ÎļþÃèÊö·ûfd
ÎļþÃèÊö·û£¨File descriptor£©ÊǼÆËã»ú¿ÆÑ§ÖеÄÒ»¸öÊõÓÊÇÒ»¸öÓÃÓÚ±íÊöÖ¸ÏòÎļþµÄÒýÓõijéÏ󻯸ÅÄî¡£
ÎļþÃèÊö·ûÔÚÐÎʽÉÏÊÇÒ»¸ö·Ç¸ºÕûÊý¡£Êµ¼ÊÉÏ£¬ËüÊÇÒ»¸öË÷ÒýÖµ£¬Ö¸ÏòÄÚºËΪÿһ¸ö½ø³ÌËùά»¤µÄ¸Ã½ø³Ì´ò¿ªÎļþµÄ¼Ç¼±í¡£µ±³ÌÐò´ò¿ªÒ»¸öÏÖÓÐÎļþ»òÕß´´½¨Ò»¸öÐÂÎļþʱ£¬ÄÚºËÏò½ø³Ì·µ»ØÒ»¸öÎļþÃèÊö·û¡£ÔÚ³ÌÐòÉè¼ÆÖУ¬Ò»Ð©Éæ¼°µ×²ãµÄ³ÌÐò±àдÍùÍù»áÎ§ÈÆ×ÅÎļþÃèÊö·ûÕ¹¿ª¡£µ«ÊÇÎļþÃèÊö·ûÕâÒ»¸ÅÄîÍùÍùÖ»ÊÊÓÃÓÚUNIX¡¢LinuxÕâÑùµÄ²Ù×÷ϵͳ¡£
5¡¢»º´æ I/O
»º´æ I/O ÓÖ±»³Æ×÷±ê×¼ I/O£¬´ó¶àÊýÎļþϵͳµÄĬÈÏ I/O ²Ù×÷¶¼ÊÇ»º´æ
I/O¡£ÔÚ Linux µÄ»º´æ I/O »úÖÆÖУ¬²Ù×÷ϵͳ»á½« I/O µÄÊý¾Ý»º´æÔÚÎļþϵͳµÄÒ³»º´æ£¨
page cache £©ÖУ¬Ò²¾ÍÊÇ˵£¬Êý¾Ý»áÏȱ»¿½±´µ½²Ù×÷ϵͳÄں˵Ļº³åÇøÖУ¬È»ºó²Å»á´Ó²Ù×÷ϵͳÄں˵Ļº³åÇø¿½±´µ½Ó¦ÓóÌÐòµÄµØÖ·¿Õ¼ä¡£Óû§¿Õ¼äû·¨Ö±½Ó·ÃÎÊÄں˿ռäµÄ£¬ÄÚºË̬µ½Óû§Ì¬µÄÊý¾Ý¿½±´¡£
»º´æ I/O µÄȱµã£º
Êý¾ÝÔÚ´«Êä¹ý³ÌÖÐÐèÒªÔÚÓ¦ÓóÌÐòµØÖ·¿Õ¼äºÍÄں˽øÐжà´ÎÊý¾Ý¿½±´²Ù×÷£¬ÕâЩÊý¾Ý¿½±´²Ù×÷Ëù´øÀ´µÄ
CPU ÒÔ¼°Äڴ濪ÏúÊǷdz£´óµÄ¡£
±¾ÎÄÌÖÂ۵ı³¾°ÊÇLinux»·¾³ÏµÄnetwork IO¡£
IO·¢ÉúÊ±Éæ¼°µÄ¶ÔÏóºÍ²½Ö裺
¶ÔÓÚÒ»¸önetwork IO (ÕâÀïÎÒÃÇÒÔread¾ÙÀý)£¬Ëü»áÉæ¼°µ½Á½¸öϵͳ¶ÔÏó£¬
1¡¢Ò»¸öÊǵ÷ÓÃÕâ¸öIOµÄprocess (or thread)£¬
2¡¢ÁíÒ»¸ö¾ÍÊÇϵͳÄÚºË(kernel)¡£
µ±Ò»¸öread²Ù×÷·¢Éúʱ£¬Ëü»á¾ÀúÁ½¸ö½×¶Î£º
1¡¢µÈ´ýÊý¾Ý×¼±¸ (Waiting for the data to
be ready)
2¡¢½«Êý¾Ý´ÓÄں˿½±´µ½½ø³ÌÖÐ (Copying the data
from the kernel to the process)
¼ÇסÕâÁ½µãºÜÖØÒª£¬ÒòΪÕâЩIO ModelµÄÇø±ð¾ÍÊÇÔÚÁ½¸ö½×¶ÎÉϸ÷Óв»Í¬µÄÇé¿ö¡£
³£¼ûµÄ¼¸ÖÖIO Ä£ÐÍ£º
1.blocking IO £¨×èÈûIO£©
2.nonblocking IO £¨·Ç×èÈûIO£©
3.IO multiplexing £¨IO¶à·¸´Óã©
4.signal driven IO £¨ÐźÅÇý¶¯Ê½IO£©
5.asynchronous IO £¨Òì²½IO£©
Ò»¡¢²»³£ÓõÄIOÄ£ÐÍ
1¡¢ÐźÅÇý¶¯IOÄ£ÐÍ£¨Signal-driven IO£©
ʹÓÃÐźţ¬ÈÃÄÚºËÔÚÃèÊö·û¾ÍÐ÷ʱ·¢ËÍSIGIOÐźÅ֪ͨӦÓóÌÐò£¬³ÆÕâÖÖÄ£ÐÍΪÐźÅÇý¶¯Ê½I/O£¨signal-driven
I/O£©¡£
ÔÀíͼ£º

Ê×ÏÈ¿ªÆôÌ×½Ó×ÖµÄÐźÅÇý¶¯Ê½I/O¹¦ÄÜ£¬²¢Í¨¹ýsigactionϵͳµ÷Óð²×°Ò»¸öÐźŴ¦Àíº¯Êý¡£¸Ãϵͳµ÷Óý«Á¢¼´·µ»Ø£¬ÎÒÃǵĽø³Ì¼ÌÐø¹¤×÷£¬Ò²¾ÍÊÇ˵½ø³ÌûÓб»×èÈû¡£µ±Êý¾Ý±¨×¼±¸ºÃ¶Áȡʱ£¬Äں˾ÍΪ¸Ã½ø³Ì²úÉúÒ»¸öSIGIOÐźš£Ëæºó¾Í¿ÉÒÔÔÚÐźŴ¦Àíº¯ÊýÖе÷ÓÃrecvfrom¶ÁÈ¡Êý¾Ý±¨£¬²¢Í¨ÖªÖ÷Ñ»·Êý¾ÝÒѾ׼±¸ºÃ´ý´¦Àí£¬Ò²¿ÉÒÔÁ¢¼´Í¨ÖªÖ÷Ñ»·£¬ÈÃËü¶ÁÈ¡Êý¾Ý±¨¡£
ÎÞÂÛÈçºÎ´¦ÀíSIGIOÐźţ¬ÕâÖÖÄ£Ð͵ÄÓÅÊÆÔÚÓڵȴýÊý¾Ý±¨µ½´ïÆÚ¼ä½ø³Ì²»±»×èÈû¡£Ö÷Ñ»·¿ÉÒÔ¼ÌÐøÖ´ÐÐ
£¬Ö»ÒªµÈµ½À´×ÔÐźŴ¦Àíº¯ÊýµÄ֪ͨ£º¼È¿ÉÒÔÊÇÊý¾ÝÒÑ×¼±¸ºÃ±»´¦Àí£¬Ò²¿ÉÒÔÊÇÊý¾Ý±¨ÒÑ×¼±¸ºÃ±»¶ÁÈ¡¡£
¶þ¡¢³£ÓõÄËÄÖÖIOÄ£ÐÍ£º
1¡¢ blocking IO£¨×èÈûIOÄ£ÐÍ£©
ÔÀíͼ£º

ʾÀý£ºÒ»ÊÕÒ»·¢³ÌÐò»á½øÈëËÀÑ»·
server.py
1
#!/usr/bin/env python
2 # -*- coding:utf-8 -*-
3 #Author: nulige
4
5 import socket
6
7 sk=socket.socket()
8
9 sk.bind(("127.0.0.1",8080))
10
11 sk.listen(5)
12
13 while 1:
14 conn,addr=sk.accept()
15
16 while 1:
17 conn.send("hello client".encode("utf8"))
18 data=conn.recv(1024)
19 print(data.decode("utf8")) |
client.py
1
#!/usr/bin/env python
2 # -*- coding:utf-8 -*-
3 #Author: nulige
4
5 import socket
6
7 sk=socket.socket()
8
9 sk.connect(("127.0.0.1",8080))
10
11 while 1:
12 data=sk.recv(1024)
13 print(data.decode("utf8"))
14 sk.send(b"hello server") |
µ±Óû§½ø³Ìµ÷ÓÃÁËrecvfromÕâ¸öϵͳµ÷Óã¬kernel¾Í¿ªÊ¼ÁËIOµÄµÚÒ»¸ö½×¶Î£º×¼±¸Êý¾Ý¡£¶ÔÓÚnetwork
ioÀ´Ëµ£¬ºÜ¶àʱºòÊý¾ÝÔÚÒ»¿ªÊ¼»¹Ã»Óе½´ï£¨±ÈÈ磬»¹Ã»ÓÐÊÕµ½Ò»¸öÍêÕûµÄUDP°ü£©£¬Õâ¸öʱºòkernel¾ÍÒªµÈ´ý×ã¹»µÄÊý¾Ýµ½À´¡£¶øÔÚÓû§½ø³ÌÕâ±ß£¬Õû¸ö½ø³Ì»á±»×èÈû¡£µ±kernelÒ»Ö±µÈµ½Êý¾Ý×¼±¸ºÃÁË£¬Ëü¾Í»á½«Êý¾Ý´ÓkernelÖп½±´µ½Óû§Äڴ棬Ȼºókernel·µ»Ø½á¹û£¬Óû§½ø³Ì²Å½â³ýblockµÄ״̬£¬ÖØÐÂÔËÐÐÆðÀ´¡£
ËùÒÔ£¬blocking IOµÄÌØµã¾ÍÊÇÔÚIOÖ´ÐеÄÁ½¸ö½×¶Î¶¼±»blockÁË¡£
2¡¢non-blocking IO(·Ç×èÈûIO)
ÔÀíͼ£º

´ÓͼÖпÉÒÔ¿´³ö£¬µ±Óû§½ø³Ì·¢³öread²Ù×÷ʱ£¬Èç¹ûkernelÖеÄÊý¾Ý»¹Ã»ÓÐ×¼±¸ºÃ£¬ÄÇôËü²¢²»»áblockÓû§½ø³Ì£¬¶øÊÇÁ¢¿Ì·µ»ØÒ»¸öerror¡£´ÓÓû§½ø³Ì½Ç¶È½²
£¬Ëü·¢ÆðÒ»¸öread²Ù×÷ºó£¬²¢²»ÐèÒªµÈ´ý£¬¶øÊÇÂíÉϾ͵õ½ÁËÒ»¸ö½á¹û¡£Óû§½ø³ÌÅжϽá¹ûÊÇÒ»¸öerrorʱ£¬Ëü¾ÍÖªµÀÊý¾Ý»¹Ã»ÓÐ×¼±¸ºÃ£¬ÓÚÊÇËü¿ÉÒÔÔٴη¢ËÍread²Ù×÷¡£Ò»µ©kernelÖеÄÊý¾Ý×¼±¸ºÃÁË£¬²¢ÇÒÓÖÔÙ´ÎÊÕµ½ÁËÓû§½ø³ÌµÄsystem
call£¬ÄÇôËüÂíÉϾͽ«Êý¾Ý¿½±´µ½ÁËÓû§Äڴ棬Ȼºó·µ»Ø¡£
ËùÒÔ£¬Óû§½ø³ÌÆäʵÊÇÐèÒª²»¶ÏµÄÖ÷¶¯Ñ¯ÎÊkernelÊý¾ÝºÃÁËûÓС£
×¢Ò⣺
ÔÚÍøÂçIOʱºò£¬·Ç×èÈûIOÒ²»á½øÐÐrecvformϵͳµ÷Ó㬼ì²éÊý¾ÝÊÇ·ñ×¼±¸ºÃ£¬Óë×èÈûIO²»Ò»Ñù£¬¡±·Ç×èÈû½«´óµÄÕûƬʱ¼äµÄ×èÈû·Ö³ÉN¶àµÄСµÄ×èÈû,
ËùÒÔ½ø³Ì²»¶ÏµØÓлú»á ¡®±»¡¯ CPU¹â¹Ë¡±¡£¼´Ã¿´Îrecvformϵͳµ÷ÓÃÖ®¼ä£¬cpuµÄȨÏÞ»¹ÔÚ½ø³ÌÊÖÖУ¬Õâ¶Îʱ¼äÊÇ¿ÉÒÔ×öÆäËûÊÂÇéµÄ£¬
Ò²¾ÍÊÇ˵·Ç×èÈûµÄrecvformϵͳµ÷Óõ÷ÓÃÖ®ºó£¬½ø³Ì²¢Ã»Óб»×èÈû£¬ÄÚºËÂíÉÏ·µ»Ø¸ø½ø³Ì£¬Èç¹ûÊý¾Ý»¹Ã»×¼±¸ºÃ£¬´Ëʱ»á·µ»ØÒ»¸öerror¡£½ø³ÌÔÚ·µ»ØÖ®ºó£¬¿ÉÒԸɵã±ðµÄÊÂÇ飬ȻºóÔÙ·¢Æðrecvformϵͳµ÷Óá£Öظ´ÉÏÃæµÄ¹ý³Ì£¬Ñ»·Íù¸´µÄ½øÐÐrecvformϵͳµ÷Óá£Õâ¸ö¹ý³Ìͨ³£±»³ÆÖ®ÎªÂÖѯ¡£ÂÖѯ¼ì²éÄÚºËÊý¾Ý£¬Ö±µ½Êý¾Ý×¼±¸ºÃ£¬ÔÙ¿½±´Êý¾Ýµ½½ø³Ì£¬½øÐÐÊý¾Ý´¦Àí¡£ÐèҪעÒ⣬¿½±´Êý¾ÝÕû¸ö¹ý³Ì£¬½ø³ÌÈÔÈ»ÊÇÊôÓÚ×èÈûµÄ״̬¡£
ʾÀý£º
·þÎñ¶Ë£º
1
import time
2 import socket
3 sk = socket.socket(socket.AF_INET,socket.SOCK_STREAM)
4 sk.bind(('127.0.0.1',6667))
5 sk.listen(5)
6 sk.setblocking(False) #ÉèÖóɷÇ×èÈû״̬
7 while True:
8 try:
9 print ('waiting client connection .......')
10 connection,address = sk.accept() # ½ø³ÌÖ÷¶¯ÂÖѯ
11 print("+++",address)
12 client_messge = connection.recv(1024)
13 print(str(client_messge,'utf8'))
14 connection.close()
15 except Exception as e: #²¶×½´íÎó
16 print (e)
17 time.sleep(4) #ÿ4Ãë´òÓ¡Ò»¸ö²¶×½µ½µÄ´íÎó |
¿Í»§¶Ë£º
1
import time
2 import socket
3 sk = socket.socket(socket.AF_INET,socket.SOCK_STREAM)
4
5 while True:
6 sk.connect(('127.0.0.1',6667))
7 print("hello")
8 sk.sendall(bytes("hello","utf8"))
9 time.sleep(2)
10 break |
ȱµã£º
1¡¢·¢ËÍÁËÌ«¶àϵͳµ÷ÓÃÊý¾Ý
2¡¢Êý¾Ý´¦Àí²»¼°Ê±
3¡¢IO multiplexing£¨IO¶à·¸´Óã©
IO multiplexingÕâ¸ö´Ê¿ÉÄÜÓеãİÉú£¬µ«ÊÇÈç¹ûÎÒ˵select£¬epoll£¬´ó¸Å¾Í¶¼ÄÜÃ÷°×ÁË¡£ÓÐЩµØ·½Ò²³ÆÕâÖÖIO·½Ê½Îªevent
driven IO¡£ÎÒÃǶ¼ÖªµÀ£¬select/epollµÄºÃ´¦¾ÍÔÚÓÚµ¥¸öprocess¾Í¿ÉÒÔͬʱ´¦Àí¶à¸öÍøÂçÁ¬½ÓµÄIO¡£ËüµÄ»ù±¾ÔÀí¾ÍÊÇselect/epollÕâ¸öfunction»á²»¶ÏµÄÂÖѯËù¸ºÔðµÄËùÓÐsocket£¬µ±Ä³¸ösocketÓÐÊý¾Ýµ½´ïÁË£¬¾Í֪ͨÓû§½ø³Ì¡£
IO¶à·¸´ÓõÄÈýÖÖ·½Ê½£º
1¡¢select--->ЧÂÊ×îµÍ£¬µ«ÓÐ×î´óÃèÊö·ûÏÞÖÆ£¬ÔÚlinuxΪ1024¡£
2¡¢poll ---->ºÍselectÒ»Ñù£¬µ«Ã»ÓÐ×î´óÃèÊö·ûÏÞÖÆ¡£
3¡¢epoll --->ЧÂÊ×î¸ß£¬Ã»ÓÐ×î´óÃèÊö·ûÏÞÖÆ£¬Ö§³Öˮƽ´¥·¢Óë±ßÔµ´¥·¢¡£
IO¶à·¸´ÓõÄÓÅÊÆ£ºÍ¬Ê±¿ÉÒÔ¼àÌý¶à¸öÁ¬½Ó£¬ÓõÄÊǵ¥Ị̈߳¬ÀûÓÿÕÏÐʱ¼äʵÏÖ²¢·¢¡£

×¢Ò⣺
Linuxϵͳ£º select¡¢poll¡¢epoll
Windowsϵͳ£ºselect
Macϵͳ£ºselect¡¢poll
ÔÀíͼ£º

µ±Óû§½ø³Ìµ÷ÓÃÁËselect£¬ÄÇôÕû¸ö½ø³Ì»á±»block£¬¶øÍ¬Ê±£¬kernel»á¡°¼àÊÓ¡±ËùÓÐselect¸ºÔðµÄsocket£¬µ±ÈκÎÒ»¸ösocketÖеÄÊý¾Ý×¼±¸ºÃÁË£¬select¾Í»á·µ»Ø¡£Õâ¸öʱºòÓû§½ø³ÌÔÙµ÷ÓÃread²Ù×÷£¬½«Êý¾Ý´Ókernel¿½±´µ½Óû§½ø³Ì¡£
Õâ¸öͼºÍblocking IOµÄͼÆäʵ²¢Ã»ÓÐÌ«´óµÄ²»Í¬£¬ÊÂʵÉÏ£¬»¹¸ü²îһЩ¡£ÒòΪÕâÀïÐèҪʹÓÃÁ½¸ösystem
call (select ºÍ recvfrom)£¬¶øblocking IOÖ»µ÷ÓÃÁËÒ»¸ösystem
call (recvfrom)¡£µ«ÊÇ£¬ÓÃselectµÄÓÅÊÆÔÚÓÚËü¿ÉÒÔͬʱ´¦Àí¶à¸öconnection¡££¨¶à˵һ¾ä¡£ËùÒÔ£¬Èç¹û´¦ÀíµÄÁ¬½ÓÊý²»ÊǺܸߵϰ£¬Ê¹ÓÃselect/epollµÄweb
server²»Ò»¶¨±ÈʹÓÃmulti-threading + blocking IOµÄweb serverÐÔÄܸüºÃ£¬¿ÉÄÜÑÓ³Ù»¹¸ü´ó¡£select/epollµÄÓÅÊÆ²¢²»ÊǶÔÓÚµ¥¸öÁ¬½ÓÄÜ´¦ÀíµÃ¸ü¿ì£¬¶øÊÇÔÚÓÚÄÜ´¦Àí¸ü¶àµÄÁ¬½Ó¡££©
ÔÚIO multiplexing ModelÖУ¬Êµ¼ÊÖУ¬¶ÔÓÚÿһ¸ösocket£¬Ò»°ã¶¼ÉèÖóÉΪnon-blocking£¬µ«ÊÇ£¬ÈçÉÏͼËùʾ£¬Õû¸öÓû§µÄprocessÆäʵÊÇÒ»Ö±±»blockµÄ¡£Ö»²»¹ýprocessÊDZ»selectÕâ¸öº¯Êýblock£¬¶ø²»ÊDZ»socket
IO¸øblock¡£
×¢Òâ1£ºselectº¯Êý·µ»Ø½á¹ûÖÐÈç¹ûÓÐÎļþ¿É¶ÁÁË£¬ÄÇô½ø³Ì¾Í¿ÉÒÔͨ¹ýµ÷ÓÃaccept()»òrecv()À´ÈÃkernel½«Î»ÓÚÄÚºËÖÐ×¼±¸µ½µÄÊý¾Ýcopyµ½Óû§Çø¡£
×¢Òâ2: selectµÄÓÅÊÆÔÚÓÚ¿ÉÒÔ´¦Àí¶à¸öÁ¬½Ó£¬²»ÊÊÓÃÓÚµ¥¸öÁ¬½Ó
ʾÀý£º
server.py
1 #server.py
2
3 import socket
4 import select
5 sk=socket.socket()
6 sk.bind(("127.0.0.1",9904))
7 sk.listen(5)
8
9 while True:
10 # sk.accept() #ÎļþÃèÊö·û
11 r,w,e=select.select([sk,],[],[],5) #ÊäÈëÁÐ±í£¬Êä³öÁÐ±í£¬´íÎóÁбí,5:
ÊǼàÌý5Ãë
12 for i in r: #[sk,]
13 conn,add=i.accept()
14 print(conn)
15 print("hello")
16 print('>>>>>>') |
client.py
1
import socket
2
3 sk=socket.socket()
4
5 sk.connect(("127.0.0.1",9904))
6
7 while 1:
8 inp=input(">>").strip()
9 sk.send(inp.encode("utf8"))
10 data=sk.recv(1024)
11 print(data.decode("utf8")) |
IO¶à·¸´ÓÃÖеÄÁ½ÖÖ´¥·¢·½Ê½£º
ˮƽ´¥·¢:Èç¹ûÎļþÃèÊö·ûÒѾ¾ÍÐ÷¿ÉÒÔ·Ç×èÈûµÄÖ´ÐÐIO²Ù×÷ÁË,´Ëʱ»á´¥·¢Í¨Öª.ÔÊÐíÔÚÈÎÒâʱ¿ÌÖØ¸´¼ì²âIOµÄ״̬,
ûÓбØÒªÃ¿´ÎÃèÊö·û¾ÍÐ÷ºó¾¡¿ÉÄܶàµÄÖ´ÐÐIO.select,poll¾ÍÊôÓÚˮƽ´¥·¢¡£
±ßÔµ´¥·¢:Èç¹ûÎļþÃèÊö·û×ÔÉÏ´Î״̬¸Ä±äºóÓÐеÄIO»î¶¯µ½À´,´Ëʱ»á´¥·¢Í¨Öª.ÔÚÊÕµ½Ò»¸öIOʼþ֪ͨºóÒª¾¡¿ÉÄÜ
¶àµÄÖ´ÐÐIO²Ù×÷,ÒòΪÈç¹ûÔÚÒ»´Î֪ͨÖÐûÓÐÖ´ÐÐÍêIOÄÇô¾ÍÐèÒªµÈµ½ÏÂÒ»´ÎеÄIO»î¶¯µ½À´²ÅÄÜ»ñÈ¡µ½¾ÍÐ÷µÄÃèÊö
·û.ÐźÅÇý¶¯Ê½IO¾ÍÊôÓÚ±ßÔµ´¥·¢¡£
epoll£º¼´¿ÉÒÔ²ÉÓÃˮƽ´¥·¢,Ò²¿ÉÒÔ²ÉÓñßÔµ´¥·¢¡£
1¡¢Ë®Æ½´¥·¢
Ö»ÓÐ¸ßµçÆ½»òµÍµçƽµÄʱºò²Å´¥·¢
1-----¸ßµçƽ---´¥·¢
0-----µÍµçƽ---²»´¥·¢
ʾÀý£º
server·þÎñ¶Ë
1
#ˮƽ´¥·¢
2 import socket
3 import select
4 sk=socket.socket()
5 sk.bind(("127.0.0.1",9904))
6 sk.listen(5)
7
8 while True:
9 r,w,e=select.select([sk,],[],[],5) #inputÊäÈëÁÐ±í£¬outputÊä³öÁÐ±í£¬erron´íÎóÁбí,5:
ÊǼàÌý5Ãë
10 for i in r: #[sk,]
11 print("hello")
12
13 print('>>>>>>') |
client¿Í»§¶Ë
1
import socket
2
3 sk=socket.socket()
4
5 sk.connect(("127.0.0.1",9904))
6
7 while 1:
8 inp=input(">>").strip()
9 sk.send(inp.encode("utf8"))
10 data=sk.recv(1024)
11 print(data.decode("utf8")) |
2¡¢±ßÔµ´¥·¢
1---------¸ßµçƽ--------´¥·¢
0---------µÍµçƽ--------´¥·¢
IO¶à·¸´ÓÃÓÅÊÆ£ºÍ¬Ê±¿ÉÒÔ¼àÌý¶à¸öÁ¬½Ó
ʾÀý£ºselect¿ÉÒÔ¼à¿Ø¶à¸ö¶ÔÏó
·þÎñ¶Ë
1
#ÓÅÊÆ
2 import socket
3 import select
4 sk=socket.socket()
5 sk.bind(("127.0.0.1",9904))
6 sk.listen(5)
7 inp=[sk,]
8
9 while True:
10 r,w,e=select.select(inp,[],[],5) #[sk,conn]£¬5ÊÇÿ¸ô¼¸Ãë¼àÌýÒ»´Î
11
12 for i in r: #[sk,]
13 conn,add=i.accept() #·¢ËÍϵͳµ÷ÓÃ
14 print(conn)
15 print("hello")
16 inp.append(conn)
17 # conn.recv(1024)
18 print('>>>>>>') |
¿Í»§¶Ë£º
1
import socket
2
3 sk=socket.socket()
4
5 sk.connect(("127.0.0.1",9904))
6
7 while 1:
8 inp=input(">>").strip()
9 sk.send(inp.encode("utf8"))
10 data=sk.recv(1024)
11 print(data.decode("utf8")) |
¶àÁËÒ»¸öÅжϣ¬ÓÃselect·½Ê½ÊµÏֵIJ¢·¢
ʾÀý£ºÊµÏÖ²¢·¢ÁÄÌ칦ÄÜ (select+IO¶à·¸´Óã¬ÊµÏÖ²¢·¢£©
·þÎñ¶Ë£º
1 import socket
2 import select
3 sk=socket.socket()
4 sk.bind(("127.0.0.1",8801))
5 sk.listen(5)
6 inputs=[sk,]
7 while True: #¼àÌýskºÍconn
8 r,w,e=select.select(inputs,[],[],5) #conn·¢Éú±ä»¯,sk²»±ä»¯¾Í×ßelse
9 print(len(r))
10 #ÅжÏsk or conn Ë·¢ÉúÁ˱仯
11 for obj in r:
12 if obj==sk:
13 conn,add=obj.accept()
14 print(conn)
15 inputs.append(conn)
16 else:
17 data_byte=obj.recv(1024)
18 print(str(data_byte,'utf8'))
19 inp=input('»Ø´ð%sºÅ¿Í»§>>>'%inputs.index(obj))
20 obj.sendall(bytes(inp,'utf8'))
21
22 print('>>',r) |
¿Í»§¶Ë£º
1
import socket
2 sk=socket.socket()
3 sk.connect(('127.0.0.1',8801))
4
5 while True:
6 inp=input(">>>>")
7 sk.sendall(bytes(inp,"utf8"))
8 data=sk.recv(1024)
9 print(str(data,'utf8')) |
Ö´Ðнá¹û£º
ÏÈÔËÐзþÎñ¶Ë£¬ÔÙÔËÐжà¸ö¿Í»§¶Ë£¬¾Í¿ÉÒÔÁÄÌìÀ²¡££¨¿ÉÒÔ½ÓÊÕ¶à¸ö¿Í»§¶ËÏûÏ¢£©
1 #server
2 >> [<socket.socket fd=276, family=AddressFamily.AF_INET,
type=SocketKind.SOCK_STREAM, proto=0, laddr=('127.0.0.1',
8801)>]
3 1
4 hello
5 »Ø´ð1ºÅ¿Í»§>>>word
6 >> [<socket.socket fd=344, family=AddressFamily.AF_INET,
type=SocketKind.SOCK_STREAM, proto=0, laddr=('127.0.0.1',
8801), raddr=('127.0.0.1', 54388)>]
7 1
8
9 #clinet
10 >>>>hello
11 word |
4¡¢Asynchronous I/O£¨Òì²½IO£©

Óû§½ø³Ì·¢Æðread²Ù×÷Ö®ºó£¬Á¢¿Ì¾Í¿ÉÒÔ¿ªÊ¼È¥×öÆäËüµÄÊ¡£¶øÁíÒ»·½Ã棬´ÓkernelµÄ½Ç¶È£¬µ±ËüÊܵ½Ò»¸öasynchronous
readÖ®ºó£¬Ê×ÏÈËü»áÁ¢¿Ì·µ»Ø£¬ËùÒÔ²»»á¶ÔÓû§½ø³Ì²úÉúÈκÎblock¡£È»ºó£¬kernel»áµÈ´ýÊý¾Ý×¼±¸Íê³É£¬È»ºó½«Êý¾Ý¿½±´µ½Óû§Äڴ棬µ±ÕâÒ»Çж¼Íê³ÉÖ®ºó£¬kernel»á¸øÓû§½ø³Ì·¢ËÍÒ»¸ösignal£¬¸æËßËüread²Ù×÷Íê³ÉÁË¡£
Òì²½×î´óÌØµã£ºÈ«³ÌÎÞ×èÈû
synchronous IO£¨Í¬²½IO)ºÍasynchronous IO(Òì²½IO)µÄÇø±ð£º
1.A synchronous I/O operation causes
the requesting process to be blocked until that I/O
operationcompletes;
2.An asynchronous I/O operation does
not cause the requesting process to be blocked;
Á½ÕßµÄÇø±ð¾ÍÔÚÓÚsynchronous IO×ö¡±IO operation¡±µÄʱºò»á½«process×èÈû¡££¨ÓÐÒ»¶¡µã×èÈû£¬¶¼ÊÇͬ²½IO£©°´ÕÕÕâ¸ö¶¨Ò壬֮ǰËùÊöµÄblocking
IO£¬non-blocking IO£¬IO multiplexing¶¼ÊôÓÚsynchronous IO£¨Í¬²½IO£©¡£
ͬ²½IO£º°üÀ¨ blocking IO¡¢non-blocking¡¢select¡¢poll¡¢epoll£¨¹Ê:epoolÖ»ÊÇαÒì²½¶øÒÑ£©£¨ÓÐ×èÈû£©
Òì²½IO£º°üÀ¨:asynchronous £¨ÎÞ×èÈû£©
ÎåÖÖIOÄ£ÐͱȽϣº

¾¹ýÉÏÃæµÄ½éÉÜ£¬»á·¢ÏÖnon-blocking IOºÍasynchronous
IOµÄÇø±ð»¹ÊǺÜÃ÷ÏԵġ£ÔÚnon-blocking IOÖУ¬ËäÈ»½ø³Ì´ó²¿·Öʱ¼ä¶¼²»»á±»block£¬µ«ÊÇËüÈÔȻҪÇó½ø³ÌÈ¥Ö÷¶¯µÄcheck£¬²¢ÇÒµ±Êý¾Ý×¼±¸Íê³ÉÒÔºó£¬Ò²ÐèÒª½ø³ÌÖ÷¶¯µÄÔٴε÷ÓÃrecvfromÀ´½«Êý¾Ý¿½±´µ½Óû§ÄÚ´æ¡£¶øasynchronous
IOÔòÍêÈ«²»Í¬¡£Ëü¾ÍÏñÊÇÓû§½ø³Ì½«Õû¸öIO²Ù×÷½»¸øÁËËûÈË£¨kernel£©Íê³É£¬È»ºóËûÈË×öÍêºó·¢ÐźÅ֪ͨ¡£ÔÚ´ËÆÚ¼ä£¬Óû§½ø³Ì²»ÐèҪȥ¼ì²éIO²Ù×÷µÄ״̬£¬Ò²²»ÐèÒªÖ÷¶¯µÄÈ¥¿½±´Êý¾Ý¡£
5¡¢selectorsÄ£¿éÓ¦ÓÃ
python·â×°ºÃµÄÄ£¿é£ºselectors
selectorsÄ£¿é: »áÑ¡ÔñÒ»¸ö×îÓŵIJÙ×÷ϵͳʵÏÖ·½Ê½
ʾÀý£º
select_module.py
1 import selectors
2 import socket
3
4 sel = selectors.DefaultSelector()
5
6 def accept(sock, mask):
7 conn, addr = sock.accept() # Should be ready
8 print('accepted', conn, 'from', addr)
9 conn.setblocking(False) #ÉèÖóɷÇ×èÈû
10 sel.register(conn, selectors.EVENT_READ,
read) #conn°ó¶¨µÄÊÇread
11
12 def read(conn, mask):
13 try:
14 data = conn.recv(1000) # Should be ready
15 if not data:
16 raise Exception
17 print('echoing', repr(data), 'to', conn)
18 conn.send(data) # Hope it won't block
19 except Exception as e:
20 print('closing', conn)
21 sel.unregister(conn) #½â³ý×¢²á
22 conn.close()
23
24 sock = socket.socket()
25 sock.bind(('localhost', 8090))
26 sock.listen(100)
27 sock.setblocking(False)
28 #×¢²á
29 sel.register(sock, selectors.EVENT_READ,
accept)
30 print("server....")
31
32 while True:
33 events = sel.select() #¼àÌý[sock,conn1,conn2]
34 print("events",events)
35 #Äõ½2¸öÔªËØ£¬Ò»¸ökey,Ò»¸ömask
36 for key, mask in events:
37 # print("key",key)
38 # print("mask",mask)
39 callback = key.data #°ó¶¨µÄÊÇreadº¯Êý
40 # print("callback",callback)
41 callback(key.fileobj, mask) #key.fileobj=sock,conn1,conn2 |
client.py
1 import socket
2
3 sk=socket.socket()
4
5 sk.connect(("127.0.0.1",8090))
6 while 1:
7 inp=input(">>>")
8 sk.send(inp.encode("utf8")) #·¢ËÍÄÚÈÝ
9 data=sk.recv(1024) #½ÓÊÕÐÅÏ¢
10 print(data.decode("utf8")) #´òÓ¡³öÀ´ |
Ö´Ðнá¹û£º
ÏÈÔËÐÐselect_module.py£¬ÔÙÔËÐÐclinet.py
1 #server
2
3 server....
4 events [(SelectorKey(fileobj=<socket.socket
fd=312, family=AddressFamily.AF_INET, type=SocketKind.SOCK_STREAM,
proto=0, laddr=('127.0.0.1', 8090)>, fd=312,
events=1, data=<function accept at 0x01512F60>),
1)]
5 accepted <socket.socket fd=376, family=AddressFamily.AF_INET,
type=SocketKind.SOCK_STREAM, proto=0, laddr=('127.0.0.1',
8090), raddr=('127.0.0.1', 57638)> from ('127.0.0.1',
57638)
6 events [(SelectorKey(fileobj=<socket.socket
fd=376, family=AddressFamily.AF_INET, type=SocketKind.SOCK_STREAM,
proto=0, laddr=('127.0.0.1', 8090), raddr=('127.0.0.1',
57638)>, fd=376, events=1, data=<function
read at 0x015C26A8>), 1)]
7 echoing b'hello' to <socket.socket fd=376,
family=AddressFamily.AF_INET, type=SocketKind.SOCK_STREAM,
proto=0, laddr=('127.0.0.1', 8090), raddr=('127.0.0.1',
57638)>
8 events [(SelectorKey(fileobj=<socket.socket
fd=312, family=AddressFamily.AF_INET, type=SocketKind.SOCK_STREAM,
proto=0, laddr=('127.0.0.1', 8090)>, fd=312,
events=1, data=<function accept at 0x01512F60>),
1)]
9 accepted <socket.socket fd=324, family=AddressFamily.AF_INET,
type=SocketKind.SOCK_STREAM, proto=0, laddr=('127.0.0.1',
8090), raddr=('127.0.0.1', 57675)> from ('127.0.0.1',
57675)
10 events [(SelectorKey(fileobj=<socket.socket
fd=324, family=AddressFamily.AF_INET, type=SocketKind.SOCK_STREAM,
proto=0, laddr=('127.0.0.1', 8090), raddr=('127.0.0.1',
57675)>, fd=324, events=1, data=<function
read at 0x015C26A8>), 1)]
11 echoing b'uuuu' to <socket.socket fd=324,
family=AddressFamily.AF_INET, type=SocketKind.SOCK_STREAM,
proto=0, laddr=('127.0.0.1', 8090), raddr=('127.0.0.1',
57675)>
12 events [(SelectorKey(fileobj=<socket.socket
fd=324, family=AddressFamily.AF_INET, type=SocketKind.SOCK_STREAM,
proto=0, laddr=('127.0.0.1', 8090), raddr=('127.0.0.1',
57675)>, fd=324, events=1, data=<function
read at 0x015C26A8>), 1)]
13 closing <socket.socket fd=324, family=AddressFamily.AF_INET,
type=SocketKind.SOCK_STREAM, proto=0, laddr=('127.0.0.1',
8090), raddr=('127.0.0.1', 57675)>
14 events [(SelectorKey(fileobj=<socket.socket
fd=312, family=AddressFamily.AF_INET, type=SocketKind.SOCK_STREAM,
proto=0, laddr=('127.0.0.1', 8090)>, fd=312,
events=1, data=<function accept at 0x01512F60>),
1)]
15 accepted <socket.socket fd=324, family=AddressFamily.AF_INET,
type=SocketKind.SOCK_STREAM, proto=0, laddr=('127.0.0.1',
8090), raddr=('127.0.0.1', 57876)> from ('127.0.0.1',
57876)
16 events [(SelectorKey(fileobj=<socket.socket
fd=324, family=AddressFamily.AF_INET, type=SocketKind.SOCK_STREAM,
proto=0, laddr=('127.0.0.1', 8090), raddr=('127.0.0.1',
57876)>, fd=324, events=1, data=<function
read at 0x015C26A8>), 1)]
17 echoing b'welcome' to <socket.socket fd=324,
family=AddressFamily.AF_INET, type=SocketKind.SOCK_STREAM,
proto=0, laddr=('127.0.0.1', 8090), raddr=('127.0.0.1',
57876)>
18
19 #clinet (Æô¶¯Á½¸öclient)
20 >>>hello
21 hello
22
23 >>>welcome
24 welcome |
6¡¢I/O¶à·¸´ÓõÄÓ¦Óó¡¾°
£¨1£©µ±¿Í»§´¦Àí¶à¸öÃèÊö×Öʱ£¨Ò»°ãÊǽ»»¥Ê½ÊäÈëºÍÍøÂçÌ×½Ó¿Ú£©£¬±ØÐëʹÓÃI/O¸´Óá£
£¨2£©µ±Ò»¸ö¿Í»§Í¬Ê±´¦Àí¶à¸öÌ×½Ó¿Úʱ£¬¶øÕâÖÖÇé¿öÊÇ¿ÉÄܵ쬵«ºÜÉÙ³öÏÖ¡£
£¨3£©Èç¹ûÒ»¸öTCP·þÎñÆ÷¼ÈÒª´¦Àí¼àÌýÌ×½Ó¿Ú£¬ÓÖÒª´¦ÀíÒÑÁ¬½ÓÌ×½Ó¿Ú£¬Ò»°ãÒ²ÒªÓõ½I/O¸´Óá£
£¨4£©Èç¹ûÒ»¸ö·þÎñÆ÷¼´Òª´¦ÀíTCP£¬ÓÖÒª´¦ÀíUDP£¬Ò»°ãҪʹÓÃI/O¸´Óá£
£¨5£©Èç¹ûÒ»¸ö·þÎñÆ÷Òª´¦Àí¶à¸ö·þÎñ»ò¶à¸öÐÒ飬һ°ãҪʹÓÃI/O¸´Óá£
'''Óë¶à½ø³ÌºÍ¶àÏ̼߳¼ÊõÏà±È£¬I/O¶à·¸´Óü¼ÊõµÄ×î´óÓÅÊÆÊÇϵͳ¿ªÏúС£¬ÏµÍ³²»±Ø´´½¨½ø³Ì/Ị̈߳¬Ò²²»±ØÎ¬»¤ÕâЩ½ø³Ì/Ị̈߳¬´Ó¶ø´ó´ó¼õСÁËϵͳµÄ¿ªÏú¡£'''
×îºó£¬Ôپټ¸¸ö²»ÊǺÜÇ¡µ±µÄÀý×ÓÀ´ËµÃ÷ÕâËĸöIO Model:
ÓÐA£¬B£¬C£¬DËĸöÈËÔÚµöÓ㣺
AÓõÄÊÇ×îÀÏʽµÄÓã¸Í£¬ËùÒÔÄØ£¬µÃÒ»Ö±ÊØ×Å£¬µÈµ½ÓãÉϹ³ÁËÔÙÀ¸Ë£»¡¾×èÈû¡¿
BµÄÓã¸ÍÓиö¹¦ÄÜ£¬Äܹ»ÏÔʾÊÇ·ñÓÐÓãÉϹ³£¨Õâ¸öÏÔʾ¹¦ÄÜһֱȥÅжÏÓãÊÇ·ñÉϹ³£©£¬ËùÒÔÄØ£¬B¾ÍºÍÅԱߵÄMMÁÄÌ죬¸ô»áÔÙ¿´¿´ÓÐûÓÐÓãÉϹ³£¬Óеϰ¾ÍѸËÙÀ¸Ë£»¡¾·Ç×èÈû¡¿
CÓõÄÓã¸ÍºÍB²î²»¶à£¬µ«ËûÏëÁËÒ»¸öºÃ°ì·¨£¬¾ÍÊÇͬʱ·ÅºÃ¼¸¸ùÓã¸Í£¬È»ºóÊØÔÚÅԱߣ¬Ò»µ©ÓÐÏÔʾ˵ÓãÉϹ³ÁË£¬Ëü¾Í½«¶ÔÓ¦µÄÓã¸ÍÀÆðÀ´£»¡¾Í¬²½¡¿
DÊǸöÓÐÇ®ÈË£¬¸É´à¹ÍÁËÒ»¸öÈ˰ïËûµöÓ㣬һµ©ÄǸöÈ˰ÑÓãµöÉÏÀ´ÁË£¬¾Í¸øD·¢¸ö¶ÌÐÅ£¨ÏûÏ¢»Øµô»úÖÆ£¬Ö÷¶¯¸æÖª£©¡£¡¾Òì²½¡¿
|