IO澶氳矾澶嶇敤

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了IO澶氳矾澶嶇敤相关的知识,希望对你有一定的参考价值。

鏍囩锛?a href='http://www.mamicode.com/so/1/%e6%ac%a1%e6%95%b0' title='娆℃暟'>娆℃暟   bin   file   娑堟伅   闆嗗悎   榛樿   condition   

涓€銆両O妯″瀷浠嬬粛

銆€銆€1锛屼富瑕佺殑浜旂妯″瀷锛氶樆濉濱O銆侀潪闃诲IO銆両O澶氳矾澶嶇敤銆佷俊鍙烽┍鍔↖O锛堜笉甯哥敤锛夈€佸紓姝O

銆€銆€瀵逛簬涓€涓猲etwork IO锛屽畠浼氭秹鍙婂埌涓や釜绯荤粺瀵硅薄锛屼竴涓槸璋冪敤杩欎釜IO鐨刾rocess锛圱hread锛夛紝鍙︿竴涓槸绯荤粺鍐呮牳銆傚綋涓€涓猺ead/recv璇绘暟鎹殑鎿嶄綔鍙戠敓鏃讹紝璇ユ搷浣滀細缁忓巻涓や釜闃舵锛?/p>

銆€銆€锛?锛夌瓑寰呮暟鎹噯澶?/p>

銆€銆€锛?锛夊皢鏁版嵁浠庡唴鏍告嫹璐濆埌杩涚▼涓?/p>

銆€銆€2锛屾敞鎰?/p>

#1銆佽緭鍏ユ搷浣滐細read銆乺eadv銆乺ecv銆乺ecvfrom銆乺ecvmsg鍏?涓嚱鏁帮紝濡傛灉浼氶樆濉炵姸鎬侊紝鍒欎細缁忕悊wait data鍜宑opy data涓や釜闃舵锛屽鏋滆缃负闈為樆濉炲垯鍦╳ait 涓嶅埌data鏃舵姏鍑哄紓甯?/span>

#2銆佽緭鍑烘搷浣滐細write銆亀ritev銆乻end銆乻endto銆乻endmsg鍏?涓嚱鏁帮紝鍦ㄥ彂閫佺紦鍐插尯婊′簡浼氶樆濉炲湪鍘熷湴锛屽鏋滆缃负闈為樆濉烇紝鍒欎細鎶涘嚭寮傚父

#3銆佹帴鏀跺鏉ラ摼鎺ワ細accept锛屼笌杈撳叆鎿嶄綔绫讳技

#4銆佸彂璧峰鍑洪摼鎺ワ細connect锛屼笌杈撳嚭鎿嶄綔绫讳技

浜屻€侀樆濉濱O

鎶€鏈垎浜浘鐗? src=

銆€銆€褰撶敤鎴疯繘绋嬭皟鐢ㄤ簡recvfrom锛岀劧鍚庣郴缁熻皟鐢紝kernel灏卞紑濮嬩簡IO鐨勭涓€闃舵锛氬噯澶囨暟鎹€傚浜巒etwork IO鏉ヨ锛屽緢澶氭椂鍊欐暟鎹湪涓€寮€濮嬭繕娌″埌杈撅紝杩欎釜鏃跺€檏ernel灏辫绛夊緟鏁版嵁鍒版潵锛岃€屽湪鐢ㄦ埛杩涚▼杩欒竟锛屾暣涓繘绋嬩細琚樆濉炪€傚綋kernel涓€鐩寸瓑鍒版暟鎹噯澶囧ソ浜嗭紝瀹冨氨浼氬皢鏁版嵁浠巏ernel涓嫹璐濆埌鐢ㄦ埛鍐呭瓨锛岀劧鍚巏ernel杩斿洖缁撴灉锛岀敤鎴疯繘绋嬫墠鎺ヨЕblock鐨勭姸鎬侊紝閲嶆柊杩愯璧锋潵銆?/p>

涓夈€侀潪闃诲IO

鎶€鏈垎浜浘鐗? src=

銆€銆€褰撶敤鎴疯繘绋嬪彂鍑簉ead鎿嶄綔鏃讹紝濡傛灉kernel涓殑鏁版嵁杩樻病鍑嗗濂斤紝閭d箞瀹冨苟涓嶄細block鐢ㄦ埛杩涚▼锛岃€屾槸绔嬪埢杩斿洖涓€涓猠rror銆傚綋鐢ㄦ埛杩涚▼鎺ユ敹鍒颁竴涓猠rror锛屽氨浼氱煡閬撴暟鎹繕娌″噯澶囷紝浜庢槸鐢ㄦ埛灏卞彲浠ュ仛鐐瑰叾浠栫殑锛岃繃涓€娈垫椂闂达紝鍐嶆鍙戦€乺ead鎿嶄綔锛屼竴鏃ernel鐨勬暟鎹噯澶囧ソ浜嗭紝浠栧氨浼氱珛椹妸鏁版嵁鎷疯礉鍒颁簡鐢ㄦ埛鍐呭瓨锛岀劧鍚庤繑鍥炪€?/p>

銆€銆€鍦ㄨ繖绉嶉潪闃诲IO妯″紡涓嬶紝鐢ㄦ埛杩涚▼灏变笉鏂殑璇㈤棶kernel鐨勬暟鎹噯澶囧ソ浜嗘病锛岃嫢娌℃湁锛岃繑鍥炵粰 鐢ㄦ埛涓€涓猠rror锛屽湪涓ゆ璇㈤棶鏈熼棿锛岀敤鎴疯繘绋嬪彲浠ュ共鐐瑰叾浠栫殑锛岃嫢鏁版嵁鍑嗗濂戒簡锛屽氨鐩存帴鎷疯礉锛岃繖涓闂繃绋嬪彨杞銆傚湪鎷疯礉鏁版嵁鏁翠釜杩囩▼锛岃繘绋嬩换浠嶇劧澶勪簬闃诲鐘舵€?/p>

鈥?/p>

socket鏈嶅姟绔?br>import socket,time
server=socket.socket()
ip_port=(鈥?/span>127.0.0.1鈥?/span>,8888)
server.bind(ip_port)
server.listen()
server.setblocking(False)
while 1:
    try:
        conn,addr=server.accept()
        break
    except Exception:
        print(鈥?/span>绛夊緟杩炴帴銆傘€傘€傘€傘€?/span>鈥?/span>)
    time.sleep(1)
while 1:
    try:
        msg=conn.recv(1024)
        print(msg.decode(鈥?/span>utf-8鈥?/span>))
    except Exception:
        print(鈥?/span>绛夊緟鎺ユ敹娑堟伅銆傘€傘€傘€?/span>鈥?/span>)
    time.sleep(1)
socket瀹㈡埛绔?/pre>
import socket
client=socket.socket()
ip_port=(鈥?27.0.0.1鈥?8888)
client.connect(ip_port)
while 1:
msg=input(鈥樿杈撳叆锛氣€?
client.send(msg.encode(鈥榰tf-8鈥?)

鍥涖€佸璺鐢↖O锛圛O multiplexing锛?/h2>

銆€銆€鐩稿綋浜巗electepoll锛岃繖绉岻O鏂瑰紡涔熺О涓轰簨浠堕┍鍔↖O锛宻electepoll鐨勫ソ澶勫湪浜庡崟涓猵rocess灏卞彲浠ュ悓鏃跺鐞嗗涓綉缁滆繛鎺ョ殑IO銆傚畠鐨勫熀鏈師鐞嗗氨鏄痵electepoll杩欎釜function浼氫笉鏂殑杞鎵€璐熻矗鐨勬墍鏈塻ocket锛屽綋鏌愪釜socket鏈夋暟鎹搷搴斾簡锛屽氨閫氱煡鐢ㄦ埛杩涚▼銆?/p>

鎶€鏈垎浜浘鐗? src=

銆€銆€褰撶敤鎴疯繘绋嬭皟鐢ㄤ簡select锛岄偅涔堟暣涓繘绋嬩細琚玝lock锛岃€屽悓鏃讹紝kernel浼氣€滅洃瑙嗏€濇墍鏈塻elect璐熻矗鐨剆ocket锛屽綋浠讳綍涓€涓猻ocket涓殑鏁版嵁鍑嗗濂戒簡锛宻elect灏变細杩斿洖銆傝繖涓椂鍊欑敤鎴疯繘绋嬪啀璋冪敤read鎿嶄綔锛屽皢鏁版嵁浠巏ernel鎷疯礉鍒扮敤鎴疯繘绋嬨€?br data-filtered="filtered">銆€銆€杩欎釜鍥惧拰blocking IO鐨勫浘鍏跺疄骞舵病鏈夊お澶х殑涓嶅悓锛屼簨瀹炰笂杩樻洿宸竴浜涖€傚洜涓哄畠涓嶄粎闃诲浜嗚繕澶氶渶瑕佷娇鐢ㄤ袱涓郴缁熻皟鐢?select鍜宺ecvfrom)锛岃€宐locking IO鍙皟鐢ㄤ簡涓€涓郴缁熻皟鐢?recvfrom)锛屽綋鍙湁涓€涓繛鎺ヨ姹傜殑鏃跺€欙紝杩欎釜妯″瀷杩樹笉濡傞樆濉濱O鏁堢巼楂樸€備絾鏄紝鐢╯elect鐨勪紭鍔垮湪浜庡畠鍙互鍚屾椂澶勭悊澶氫釜connection锛岃€岄樆濉濱O閭i噷涓嶈兘锛屾垜涓嶇闃诲涓嶉樆濉烇紝浣犳墍鏈夌殑杩炴帴鍖呮嫭recv绛夋搷浣滐紝鎴戦兘甯綘鐩戝惉鐫€锛堜互浠€涔堝舰寮忕洃鍚殑鍛紵鍏堜笉瑕佽€冭檻锛屼笅闈細璁茬殑~~锛夛紝鍏朵腑浠讳綍涓€涓湁鍙樺姩锛堟湁閾炬帴锛屾湁鏁版嵁锛夛紝鎴戝氨鍛婅瘔浣犵敤鎴凤紝閭d箞浣犲氨鍙互鍘昏皟鐢ㄨ繖涓暟鎹簡锛岃繖灏辨槸浠栫殑NB涔嬪銆傝繖涓狪O澶氳矾澶嶇敤妯″瀷鏈哄埗鏄搷浣滅郴缁熷府鎴戜滑鎻愪緵鐨勶紝鍦╳indows涓婃湁杩欎箞涓満鍒跺彨鍋歴elect锛岄偅涔堝鏋滄垜浠兂閫氳繃鑷繁鍐欎唬鐮佹潵鎺у埗杩欎釜鏈哄埗鎴栬€呰嚜宸卞啓杩欎箞涓満鍒讹紝鎴戜滑鍙互浣跨敤python涓殑select妯″潡鏉ュ畬鎴愪笂闈㈣繖涓€绯诲垪浠g悊鐨勮涓恒€傚湪涓€鍒囩殕鏂囦欢鐨剈nix涓嬶紝杩欎簺鍙互鎺ユ敹鏁版嵁鐨勫璞℃垨鑰呰繛鎺ワ紝閮藉彨鍋氭枃浠舵弿杩扮fd

銆€銆€select妯″潡鍙婁娇鐢ㄦ柟娉曪細select鐨勪紭鍔垮湪浜庡鐞嗗涓繛鎺ワ紝涓嶉€傜敤浜庡崟涓繛鎺?/span>

import select

fd_r_list, fd_w_list, fd_e_list = select.select(rlist, wlist, xlist, [timeout])

鍙傛暟锛?鍙帴鍙楀洓涓弬鏁帮紙鍓嶄笁涓繀椤伙級
    rlist: wait until ready for reading  #绛夊緟璇荤殑瀵硅薄锛屼綘闇€瑕佺洃鍚殑闇€瑕佽幏鍙栨暟鎹殑瀵硅薄鍒楄〃
    wlist: wait until ready for writing  #绛夊緟鍐欑殑瀵硅薄锛屼綘闇€瑕佸啓涓€浜涘唴瀹圭殑鏃跺€欙紝input绛夌瓑锛屼篃灏辨槸璇存垜浼氬惊鐜粬鐪嬬湅鏄惁鏈夐渶瑕佸彂閫佺殑娑堟伅锛屽鏋滄湁鎴戝彇鍑鸿繖涓璞$殑娑堟伅骞跺彂閫佸嚭鍘伙紝涓€鑸敤涓嶅埌锛岃繖閲屾垜浠篃缁欎竴涓猍]銆?/span>
    xlist: wait for an 鈥渆xceptional condition鈥? #绛夊緟寮傚父鐨勫璞★紝涓€浜涢澶栫殑鎯呭喌锛屼竴鑸敤涓嶅埌锛屼絾鏄繀椤讳紶锛岄偅涔堟垜浠氨缁欎粬涓€涓猍]銆?/span>
    timeout: 瓒呮椂鏃堕棿
    褰撹秴鏃舵椂闂?锛?n(姝f暣鏁?鏃讹紝閭d箞濡傛灉鐩戝惉鐨勫彞鏌勫潎鏃犱换浣曞彉鍖栵紝鍒檚elect浼氶樆濉瀗绉掞紝涔嬪悗杩斿洖涓変釜绌哄垪琛紝濡傛灉鐩戝惉鐨勫彞鏌勬湁鍙樺寲锛屽垯鐩存帴鎵ц銆?杩斿洖鍊硷細涓変釜鍒楄〃涓庝笂闈㈢殑涓変釜鍙傛暟鍒楄〃鏄搴旂殑
銆€銆€select鏂规硶鐢ㄦ潵鐩戣鏂囦欢鎻忚堪绗?褰撴枃浠舵弿杩扮鏉′欢涓嶆弧瓒虫椂锛宻elect浼氶樆濉?锛屽綋鏌愪釜鏂囦欢鎻忚堪绗︾姸鎬佹敼鍙樺悗锛屼細杩斿洖涓変釜鍒楄〃
    1銆佸綋鍙傛暟1 搴忓垪涓殑fd婊¤冻鈥滃彲璇烩€濇潯浠舵椂锛屽垯鑾峰彇鍙戠敓鍙樺寲鐨刦d骞舵坊鍔犲埌fd_r_list涓?    2銆佸綋鍙傛暟2 搴忓垪涓惈鏈塮d鏃讹紝鍒欏皢璇ュ簭鍒椾腑鎵€鏈夌殑fd娣诲姞鍒?fd_w_list涓?    3銆佸綋鍙傛暟3 搴忓垪涓殑fd鍙戠敓閿欒鏃讹紝鍒欏皢璇ュ彂鐢熼敊璇殑fd娣诲姞鍒?fd_e_list涓?    4銆佸綋瓒呮椂鏃堕棿涓虹┖锛屽垯select浼氫竴鐩撮樆濉烇紝鐩村埌鐩戝惉鐨勫彞鏌勫彂鐢熷彉鍖?/pre>
#鏈嶅姟绔?/span>
from socket import *
import select
server = socket(AF_INET, SOCK_STREAM)
server.bind((鈥?/span>127.0.0.1鈥?/span>,8093))
server.listen(5)
# 璁剧疆涓洪潪闃诲
server.setblocking(False)

# 鍒濆鍖栧皢鏈嶅姟绔痵ocket瀵硅薄鍔犲叆鐩戝惉鍒楄〃锛屽悗闈㈣繕瑕佸姩鎬佹坊鍔犱竴浜沜onn杩炴帴瀵硅薄锛屽綋accept鐨勬椂鍊檚k灏辨湁鎰熷簲锛屽綋recv鐨勬椂鍊檆onn灏辨湁鍔ㄩ潤
rlist=[server,]
rdata = {}  #瀛樻斁瀹㈡埛绔彂閫佽繃鏉ョ殑娑堟伅

wlist=[]  #绛夊緟鍐欏璞?/span>
wdata={}  #瀛樻斁瑕佽繑鍥炵粰瀹㈡埛绔殑娑堟伅

print(鈥?/span>棰勫锛佺洃鍚紒锛侊紒鈥?/span>)
count = 0 #鍐欑潃璁℃暟鐢ㄧ殑锛屼负浜嗙湅瀹為獙鏁堟灉鐢ㄧ殑锛屾病鐢?/span>
while True:
    # 寮€濮?select 鐩戝惉,瀵箁list涓殑鏈嶅姟绔痵erver杩涜鐩戝惉锛宻elect鍑芥暟闃诲杩涚▼锛岀洿鍒皉list涓殑濂楁帴瀛楄瑙﹀彂锛堝湪姝や緥涓紝濂楁帴瀛楁帴鏀跺埌瀹㈡埛绔彂鏉ョ殑鎻℃墜淇″彿锛屼粠鑰屽彉寰楀彲璇伙紝婊¤冻select鍑芥暟鐨勨€滃彲璇烩€濇潯浠讹級锛岃瑙﹀彂鐨勶紙鏈夊姩闈欑殑锛夊鎺ュ瓧锛堟湇鍔″櫒濂楁帴瀛楋級杩斿洖缁欎簡rl杩欎釜杩斿洖鍊奸噷闈紱
    rl,wl,xl=select.select(rlist,wlist,[],0.5)
    print(鈥?/span>%s 娆℃暟>>鈥?/span>%(count),wl)
    count = count + 1
    # 瀵箁l杩涜寰幆鍒ゆ柇鏄惁鏈夊鎴风杩炴帴杩涙潵,褰撴湁瀹㈡埛绔繛鎺ヨ繘鏉ユ椂select灏嗚Е鍙?/span>
    for sock in rl:
        # 鍒ゆ柇褰撳墠瑙﹀彂鐨勬槸涓嶆槸socket瀵硅薄, 褰撹Е鍙戠殑瀵硅薄鏄痵ocket瀵硅薄鏃?璇存槑鏈夋柊瀹㈡埛绔痑ccept杩炴帴杩涙潵浜?/span>
        if sock == server:
            # 鎺ユ敹瀹㈡埛绔殑杩炴帴, 鑾峰彇瀹㈡埛绔璞″拰瀹㈡埛绔湴鍧€淇℃伅
            conn,addr=sock.accept()
            #鎶婃柊鐨勫鎴风杩炴帴鍔犲叆鍒扮洃鍚垪琛ㄤ腑锛屽綋瀹㈡埛绔殑杩炴帴鏈夋帴鏀舵秷鎭殑鏃跺€欙紝select灏嗚瑙﹀彂锛屼細鐭ラ亾杩欎釜杩炴帴鏈夊姩闈欙紝鏈夋秷鎭紝閭d箞杩斿洖缁檙l杩欎釜杩斿洖鍊煎垪琛ㄩ噷闈€?/span>
            rlist.append(conn)
        else:
            # 鐢变簬瀹㈡埛绔繛鎺ヨ繘鏉ユ椂socket鎺ユ敹瀹㈡埛绔繛鎺ヨ姹傦紝灏嗗鎴风杩炴帴鍔犲叆鍒颁簡鐩戝惉鍒楄〃涓?rlist)锛屽鎴风鍙戦€佹秷鎭殑鏃跺€欒繖涓繛鎺ュ皢瑙﹀彂
            # 鎵€浠ュ垽鏂槸鍚︽槸瀹㈡埛绔繛鎺ュ璞¤Е鍙?/span>
            try:
                data=sock.recv(1024)
                #娌℃湁鏁版嵁鐨勬椂鍊欙紝鎴戜滑灏嗚繖涓繛鎺ュ叧闂帀锛屽苟浠庣洃鍚垪琛ㄤ腑绉婚櫎
                if not data:
                    sock.close()
                    rlist.remove(sock)
                    continue
                print("received {0} from client {1}".format(data.decode(), sock))
                #灏嗘帴鍙楀埌鐨勫鎴风鐨勬秷鎭繚瀛樹笅鏉?/span>
                rdata[sock] = data.decode()

                #灏嗗鎴风杩炴帴瀵硅薄鍜岃繖涓璞℃帴鏀跺埌鐨勬秷鎭姞宸ユ垚杩斿洖娑堟伅锛屽苟娣诲姞鍒皐data杩欎釜瀛楀吀閲岄潰
                wdata[sock]=data.upper()
                #闇€瑕佺粰杩欎釜瀹㈡埛绔洖澶嶆秷鎭殑鏃跺€欙紝鎴戜滑灏嗚繖涓繛鎺ユ坊鍔犲埌wlist鍐欑洃鍚垪琛ㄤ腑
                wlist.append(sock)
            #濡傛灉杩欎釜杩炴帴鍑洪敊浜嗭紝瀹㈡埛绔毚鍔涙柇寮€浜嗭紙娉ㄦ剰锛屾垜杩樻病鏈夋帴鏀朵粬鐨勬秷鎭紝鎴栬€呮帴鏀朵粬鐨勬秷鎭殑杩囩▼涓嚭閿欎簡锛?/span>
            except Exception:
                #鍏抽棴杩欎釜杩炴帴
                sock.close()
                #鍦ㄧ洃鍚垪琛ㄤ腑灏嗕粬绉婚櫎锛屽洜涓轰笉绠′粈涔堝師鍥狅紝瀹冩瘯绔熸槸鏂紑浜嗭紝娌″繀瑕佸啀鐩戝惉瀹冧簡
                rlist.remove(sock)
    # 濡傛灉鐜板湪娌℃湁瀹㈡埛绔姹傝繛鎺?涔熸病鏈夊鎴风鍙戦€佹秷鎭椂锛屽紑濮嬪鍙戦€佹秷鎭垪琛ㄨ繘琛屽鐞嗭紝鏄惁闇€瑕佸彂閫佹秷鎭?/span>
    for sock in wl:
        sock.send(wdata[sock])
        wlist.remove(sock)
        wdata.pop(sock)

    # #灏嗕竴娆elect鐩戝惉鍒楄〃涓湁鎺ユ敹鏁版嵁鐨刢onn瀵硅薄鎵€鎺ユ敹鍒扮殑娑堟伅鎵撳嵃涓€涓?/span>
    # for k,v in rdata.items():
    #     print(k,鈥樺彂鏉ョ殑娑堟伅鏄細鈥?v)
    # #娓呯┖鎺ユ敹鍒扮殑娑堟伅
    # rdata.clear()

---------------------------------------
#瀹㈡埛绔?/span>
from socket import *

client=socket(AF_INET,SOCK_STREAM)
client.connect((鈥?/span>127.0.0.1鈥?/span>,8093))


while True:
    msg=input(鈥?/span>>>: 鈥?/span>).strip()
    if not msg:continue
    client.send(msg.encode(鈥?/span>utf-8鈥?/span>))
    data=client.recv(1024)
    print(data.decode(鈥?/span>utf-8鈥?/span>))

client.close()

select缃戠粶IO妯″瀷鐨勭ず渚嬩唬鐮?/span>

銆€銆€IO澶氳矾澶嶇敤鐨勬満鍒讹細

銆€銆€select鏈哄埗锛歐indows銆丩inux

銆€銆€poll鏈哄埗锛?nbsp;Linux    #鍜宭select鐩戝惉鏈哄埗涓€鏍凤紝浣嗘槸瀵圭洃鍚垪琛ㄩ噷闈㈢殑鏁伴噺娌℃湁闄愬埗锛宻elect榛樿闄愬埗鏄?024涓紝浣嗘槸浠栦滑涓や釜閮芥槸鎿嶄綔绯荤粺杞姣忎竴涓鐩戝惉鐨勬枃浠舵弿杩扮锛堝鏋滄暟閲忓緢澶э紝鍏跺疄鏁堢巼涓嶅お濂斤級锛岀湅鏄惁鏈夊彲璇绘搷浣溿€?/p>

銆€銆€epoll鏈哄埗锛?nbsp;Linux    #瀹冪殑鐩戝惉鏈哄埗鍜屼笂闈袱涓笉鍚岋紝浠栫粰姣忎竴涓洃鍚殑瀵硅薄缁戝畾浜嗕竴涓洖璋冨嚱鏁帮紝浣犺繖涓璞℃湁娑堟伅锛岄偅涔堣Е鍙戝洖璋冨嚱鏁扮粰鐢ㄦ埛锛岀敤鎴峰氨杩涜绯荤粺璋冪敤鏉ユ嫹璐濇暟鎹紝骞朵笉鏄疆璇㈢洃鍚墍鏈夌殑琚洃鍚璞★紝杩欐牱鐨勬晥鐜囬珮寰堝銆?/p>

浜斻€佸紓姝O

鎶€鏈垎浜浘鐗? src=

銆€銆€ 鐢ㄦ埛杩涚▼鍙戣捣read鎿嶄綔涔嬪悗锛岀珛鍒诲氨鍙互寮€濮嬪幓鍋氬叾瀹冪殑浜嬨€傝€屽彟涓€鏂归潰锛屼粠kernel鐨勮搴︼紝褰撳畠鍙楀埌涓€涓猘synchronous read涔嬪悗锛岄鍏堝畠浼氱珛鍒昏繑鍥烇紝鎵€浠ヤ笉浼氬鐢ㄦ埛杩涚▼浜х敓浠讳綍block銆傜劧鍚庯紝kernel鎿嶄綔绯荤粺浼氱瓑寰呮暟鎹紙闃诲锛夊噯澶囧畬鎴愶紝鐒跺悗灏嗘暟鎹嫹璐濆埌鐢ㄦ埛鍐呭瓨锛屽綋杩欎竴鍒囬兘瀹屾垚涔嬪悗锛宬ernel浼氱粰鐢ㄦ埛杩涚▼鍙戦€佷竴涓猻ignal锛屽憡璇夊畠read鎿嶄綔瀹屾垚浜嗐€?/p>

銆€銆€璨屼技寮傛IO杩欎釜妯″瀷寰堢墰~~浣嗘槸浣犲彂鐜版病鏈夛紝杩欎笉鏄垜浠嚜宸变唬鐮佹帶鍒剁殑锛岄兘鏄搷浣滅郴缁熷畬鎴愮殑锛岃€宲ython鍦╟opy鏁版嵁杩欎釜闃舵娌℃湁鎻愪緵鎿嶇旱鎿嶄綔绯荤粺鐨勬帴鍙o紝鎵€浠ョ敤python娌℃硶瀹炵幇杩欏寮傛IO鏈哄埗锛屽叾浠栧嚑涓狪O妯″瀷閮芥病鏈夎В鍐崇浜岄樁娈电殑闃诲锛堢敤鎴锋€佸拰鍐呮牳鎬佷箣闂碿opy鏁版嵁锛夛紝浣嗘槸C璇█鏄彲浠ュ疄鐜扮殑锛屽洜涓哄ぇ瀹堕兘鐭ラ亾C璇█鏄渶鎺ヨ繎搴曞眰鐨勶紝铏界劧鎴戜滑鐢╬ython瀹炵幇涓嶄簡锛屼絾鏄痯ython浠嶇劧鏈夊紓姝ョ殑妯″潡鍜屾鏋讹紙tornado銆乼wstied锛岄珮骞跺彂闇€姹傜殑鏃跺€欑敤锛夛紝杩欎簺妯″潡鍜屾鏋跺緢澶氶兘鏄敤搴曞眰鐨凜璇█瀹炵幇鐨勶紝瀹冨府鎴戜滑瀹炵幇浜嗗紓姝ワ紝浣犲彧瑕佷娇鐢ㄥ氨鍙互浜嗭紝浣嗘槸浣犺鐭ラ亾杩欎釜寮傛鏄笉鏄緢濂藉憖锛屼笉闇€瑕佷綘鑷繁绛夊緟浜嗭紝鎿嶄綔绯荤粺甯綘鍋氫簡鎵€鏈夌殑浜嬫儏锛屼綘灏辩洿鎺ユ敹鏁版嵁灏辫浜嗭紝灏卞儚浣犳湁涓€寮犻摱琛屽崱锛岄摱琛屽畾鏈熺粰浣犳墦閽变竴鏍枫€?/p>

鍏€乻electors妯″潡

鎶€鏈垎浜浘鐗? id=
IO澶嶇敤锛氫负浜嗚В閲婅繖涓悕璇嶏紝棣栧厛鏉ョ悊瑙d笅澶嶇敤杩欎釜姒傚康锛屽鐢ㄤ篃灏辨槸鍏辩敤鐨勬剰鎬濓紝杩欐牱鐞嗚В杩樻槸鏈変簺鎶借薄锛屼负姝わ紝鍜变滑鏉ョ悊瑙d笅澶嶇敤鍦ㄩ€氫俊棰嗗煙鐨勪娇鐢紝鍦ㄩ€氫俊棰嗗煙涓负浜嗗厖鍒嗗埄鐢ㄧ綉缁滆繛鎺ョ殑鐗╃悊浠嬭川锛屽線寰€鍦ㄥ悓涓€鏉$綉缁滈摼璺笂閲囩敤鏃跺垎澶嶇敤鎴栭鍒嗗鐢ㄧ殑鎶€鏈娇鍏跺湪鍚屼竴閾捐矾涓婁紶杈撳璺俊鍙凤紝鍒拌繖閲屾垜浠氨鍩烘湰涓婄悊瑙d簡澶嶇敤鐨勫惈涔夛紝鍗冲叕鐢ㄦ煇涓€滀粙璐ㄢ€濇潵灏藉彲鑳藉鐨勫仛鍚屼竴绫?鎬ц川)鐨勪簨锛岄偅IO澶嶇敤鐨勨€滀粙璐ㄢ€濇槸浠€涔堝憿锛熶负姝ゆ垜浠鍏堟潵鐪嬬湅鏈嶅姟鍣ㄧ紪绋嬬殑妯″瀷锛屽鎴风鍙戞潵鐨勮姹傛湇鍔$浼氫骇鐢熶竴涓繘绋嬫潵瀵瑰叾杩涜鏈嶅姟锛屾瘡褰撴潵涓€涓鎴疯姹傚氨浜х敓涓€涓繘绋嬫潵鏈嶅姟锛岀劧鑰岃繘绋嬩笉鍙兘鏃犻檺鍒剁殑浜х敓锛屽洜姝や负浜嗚В鍐冲ぇ閲忓鎴风璁块棶鐨勯棶棰橈紝寮曞叆浜咺O澶嶇敤鎶€鏈紝鍗筹細涓€涓繘绋嬪彲浠ュ悓鏃跺澶氫釜瀹㈡埛璇锋眰杩涜鏈嶅姟銆備篃灏辨槸璇碔O澶嶇敤鐨勨€滀粙璐ㄢ€濇槸杩涚▼(鍑嗙‘鐨勮澶嶇敤鐨勬槸select鍜宲oll锛屽洜涓鸿繘绋嬩篃鏄潬璋冪敤select鍜宲oll鏉ュ疄鐜扮殑)锛屽鐢ㄤ竴涓繘绋?select鍜宲oll)鏉ュ澶氫釜IO杩涜鏈嶅姟锛岃櫧鐒跺鎴风鍙戞潵鐨処O鏄苟鍙戠殑浣嗘槸IO鎵€闇€鐨勮鍐欐暟鎹鏁版儏鍐典笅鏄病鏈夊噯澶囧ソ鐨勶紝鍥犳灏卞彲浠ュ埄鐢ㄤ竴涓嚱鏁?select鍜宲oll)鏉ョ洃鍚琁O鎵€闇€鐨勮繖浜涙暟鎹殑鐘舵€侊紝涓€鏃O鏈夋暟鎹彲浠ヨ繘琛岃鍐欎簡锛岃繘绋嬪氨鏉ュ杩欐牱鐨処O杩涜鏈嶅姟銆?
  

鐞嗚В瀹孖O澶嶇敤鍚庯紝鎴戜滑鍦ㄦ潵鐪嬩笅瀹炵幇IO澶嶇敤涓殑涓変釜API(select銆乸oll鍜宔poll)鐨勫尯鍒拰鑱旂郴

select锛宲oll锛宔poll閮芥槸IO澶氳矾澶嶇敤鐨勬満鍒讹紝I/O澶氳矾澶嶇敤灏辨槸閫氳繃涓€绉嶆満鍒讹紝鍙互鐩戣澶氫釜鎻忚堪绗︼紝涓€鏃︽煇涓弿杩扮灏辩华锛堜竴鑸槸璇诲氨缁垨鑰呭啓灏辩华锛夛紝鑳藉閫氱煡搴旂敤绋嬪簭杩涜鐩稿簲鐨勮鍐欐搷浣溿€備絾select锛宲oll锛宔poll鏈川涓婇兘鏄悓姝/O锛屽洜涓轰粬浠兘闇€瑕佸湪璇诲啓浜嬩欢灏辩华鍚庤嚜宸辫礋璐h繘琛岃鍐欙紝涔熷氨鏄杩欎釜璇诲啓杩囩▼鏄樆濉炵殑锛岃€屽紓姝/O鍒欐棤闇€鑷繁璐熻矗杩涜璇诲啓锛屽紓姝/O鐨勫疄鐜颁細璐熻矗鎶婃暟鎹粠鍐呮牳鎷疯礉鍒扮敤鎴风┖闂淬€備笁鑰呯殑鍘熷瀷濡備笅鎵€绀猴細

int select(int nfds, fd_set *readfds, fd_set *writefds, fd_set *exceptfds, struct timeval *timeout);

int poll(struct pollfd *fds, nfds_t nfds, int timeout);

int epoll_wait(int epfd, struct epoll_event *events, int maxevents, int timeout);



 1.select鐨勭涓€涓弬鏁皀fds涓篺dset闆嗗悎涓渶澶ф弿杩扮鍊煎姞1锛宖dset鏄竴涓綅鏁扮粍锛屽叾澶у皬闄愬埗涓篲_FD_SETSIZE锛?024锛夛紝浣嶆暟缁勭殑姣忎竴浣嶄唬琛ㄥ叾瀵瑰簲鐨勬弿杩扮鏄惁闇€瑕佽妫€鏌ャ€傜浜屼笁鍥涘弬鏁拌〃绀洪渶瑕佸叧娉ㄨ銆佸啓銆侀敊璇簨浠剁殑鏂囦欢鎻忚堪绗︿綅鏁扮粍锛岃繖浜涘弬鏁版棦鏄緭鍏ュ弬鏁颁篃鏄緭鍑哄弬鏁帮紝鍙兘浼氳鍐呮牳淇敼鐢ㄤ簬鏍囩ず鍝簺鎻忚堪绗︿笂鍙戠敓浜嗗叧娉ㄧ殑浜嬩欢锛屾墍浠ユ瘡娆¤皟鐢╯elect鍓嶉兘闇€瑕侀噸鏂板垵濮嬪寲fdset銆倀imeout鍙傛暟涓鸿秴鏃舵椂闂达紝璇ョ粨鏋勪細琚唴鏍镐慨鏀癸紝鍏跺€间负瓒呮椂鍓╀綑鐨勬椂闂淬€?
 select鐨勮皟鐢ㄦ楠ゅ涓嬶細

锛?/span>1锛変娇鐢╟opy_from_user浠庣敤鎴风┖闂存嫹璐漟dset鍒板唴鏍哥┖闂?
锛?/span>2锛夋敞鍐屽洖璋冨嚱鏁癬_pollwait

锛?/span>3锛夐亶鍘嗘墍鏈塮d锛岃皟鐢ㄥ叾瀵瑰簲鐨刾oll鏂规硶锛堝浜巗ocket锛岃繖涓猵oll鏂规硶鏄痵ock_poll锛宻ock_poll鏍规嵁鎯呭喌浼氳皟鐢ㄥ埌tcp_poll,udp_poll鎴栬€卍atagram_poll锛?
锛?/span>4锛変互tcp_poll涓轰緥锛屽叾鏍稿績瀹炵幇灏辨槸__pollwait锛屼篃灏辨槸涓婇潰娉ㄥ唽鐨勫洖璋冨嚱鏁般€?
锛?/span>5锛?span style="color: #800080">__pollwait鐨勪富瑕佸伐浣滃氨鏄妸current锛堝綋鍓嶈繘绋嬶級鎸傚埌璁惧鐨勭瓑寰呴槦鍒椾腑锛屼笉鍚岀殑璁惧鏈変笉鍚岀殑绛夊緟闃熷垪锛屽浜巘cp_poll 鏉ヨ锛屽叾绛夊緟闃熷垪鏄痵k->sk_sleep锛堟敞鎰忔妸杩涚▼鎸傚埌绛夊緟闃熷垪涓苟涓嶄唬琛ㄨ繘绋嬪凡缁忕潯鐪犱簡锛夈€傚湪璁惧鏀跺埌涓€鏉℃秷鎭紙缃戠粶璁惧锛夋垨濉啓瀹屾枃浠舵暟 鎹紙纾佺洏璁惧锛夊悗锛屼細鍞ら啋璁惧绛夊緟闃熷垪涓婄潯鐪犵殑杩涚▼锛岃繖鏃禼urrent渚胯鍞ら啋浜嗐€?
锛?/span>6锛塸oll鏂规硶杩斿洖鏃朵細杩斿洖涓€涓弿杩拌鍐欐搷浣滄槸鍚﹀氨缁殑mask鎺╃爜锛屾牴鎹繖涓猰ask鎺╃爜缁檉d_set璧嬪€笺€?
锛?/span>7锛夊鏋滈亶鍘嗗畬鎵€鏈夌殑fd锛岃繕娌℃湁杩斿洖涓€涓彲璇诲啓鐨刴ask鎺╃爜锛屽垯浼氳皟鐢╯chedule_timeout鏄皟鐢╯elect鐨勮繘绋嬶紙涔熷氨鏄?current锛夎繘鍏ョ潯鐪犮€傚綋璁惧椹卞姩鍙戠敓鑷韩璧勬簮鍙鍐欏悗锛屼細鍞ら啋鍏剁瓑寰呴槦鍒椾笂鐫$湢鐨勮繘绋嬨€傚鏋滆秴杩囦竴瀹氱殑瓒呮椂鏃堕棿锛坰chedule_timeout 鎸囧畾锛夛紝杩樻槸娌′汉鍞ら啋锛屽垯璋冪敤select鐨勮繘绋嬩細閲嶆柊琚敜閱掕幏寰桟PU锛岃繘鑰岄噸鏂伴亶鍘唂d锛屽垽鏂湁娌℃湁灏辩华鐨刦d銆?
锛?/span>8锛夋妸fd_set浠庡唴鏍哥┖闂存嫹璐濆埌鐢ㄦ埛绌洪棿銆?
鎬荤粨涓媠elect鐨勫嚑澶х己鐐癸細

锛?/span>1锛夋瘡娆¤皟鐢╯elect锛岄兘闇€瑕佹妸fd闆嗗悎浠庣敤鎴锋€佹嫹璐濆埌鍐呮牳鎬侊紝杩欎釜寮€閿€鍦╢d寰堝鏃朵細寰堝ぇ

锛?/span>2锛夊悓鏃舵瘡娆¤皟鐢╯elect閮介渶瑕佸湪鍐呮牳閬嶅巻浼犻€掕繘鏉ョ殑鎵€鏈塮d锛岃繖涓紑閿€鍦╢d寰堝鏃朵篃寰堝ぇ

锛?/span>3锛塻elect鏀寔鐨勬枃浠舵弿杩扮鏁伴噺澶皬浜嗭紝榛樿鏄?024

 

2锛? poll涓巗elect涓嶅悓锛岄€氳繃涓€涓猵ollfd鏁扮粍鍚戝唴鏍镐紶閫掗渶瑕佸叧娉ㄧ殑浜嬩欢锛屾晠娌℃湁鎻忚堪绗︿釜鏁扮殑闄愬埗锛宲ollfd涓殑events瀛楁鍜宺events鍒嗗埆鐢ㄤ簬鏍囩ず鍏虫敞鐨勪簨浠跺拰鍙戠敓鐨勪簨浠讹紝鏁卲ollfd鏁扮粍鍙渶瑕佽鍒濆鍖栦竴娆°€?
 poll鐨勫疄鐜版満鍒朵笌select绫讳技锛屽叾瀵瑰簲鍐呮牳涓殑sys_poll锛屽彧涓嶈繃poll鍚戝唴鏍镐紶閫抪ollfd鏁扮粍锛岀劧鍚庡pollfd涓殑姣忎釜鎻忚堪绗﹁繘琛宲oll锛岀浉姣斿鐞唂dset鏉ヨ锛宲oll鏁堢巼鏇撮珮銆俻oll杩斿洖鍚庯紝闇€瑕佸pollfd涓殑姣忎釜鍏冪礌妫€鏌ュ叾revents鍊硷紝鏉ュ緱鎸囦簨浠舵槸鍚﹀彂鐢熴€?
 

3锛庣洿鍒癓inux2.6鎵嶅嚭鐜颁簡鐢卞唴鏍哥洿鎺ユ敮鎸佺殑瀹炵幇鏂规硶锛岄偅灏辨槸epoll锛岃鍏涓篖inux2.6涓嬫€ц兘鏈€濂界殑澶氳矾I/O灏辩华閫氱煡鏂规硶銆俥poll鍙互鍚屾椂鏀寔姘村钩瑙﹀彂鍜岃竟缂樿Е鍙戯紙Edge Triggered锛屽彧鍛婅瘔杩涚▼鍝簺鏂囦欢鎻忚堪绗﹀垰鍒氬彉涓哄氨缁姸鎬侊紝瀹冨彧璇翠竴閬嶏紝濡傛灉鎴戜滑娌℃湁閲囧彇琛屽姩锛岄偅涔堝畠灏嗕笉浼氬啀娆″憡鐭ワ紝杩欑鏂瑰紡绉颁负杈圭紭瑙﹀彂锛夛紝鐞嗚涓婅竟缂樿Е鍙戠殑鎬ц兘瑕佹洿楂樹竴浜涳紝浣嗘槸浠g爜瀹炵幇鐩稿綋澶嶆潅銆俥poll鍚屾牱鍙憡鐭ラ偅浜涘氨缁殑鏂囦欢鎻忚堪绗︼紝鑰屼笖褰撴垜浠皟鐢╡poll_wait()鑾峰緱灏辩华鏂囦欢鎻忚堪绗︽椂锛岃繑鍥炵殑涓嶆槸瀹為檯鐨勬弿杩扮锛岃€屾槸涓€涓唬琛ㄥ氨缁弿杩扮鏁伴噺鐨勫€硷紝浣犲彧闇€瑕佸幓epoll鎸囧畾鐨勪竴涓暟缁勪腑渚濇鍙栧緱鐩稿簲鏁伴噺鐨勬枃浠舵弿杩扮鍗冲彲锛岃繖閲屼篃浣跨敤浜嗗唴瀛樻槧灏勶紙mmap锛夋妧鏈紝杩欐牱渚垮交搴曠渷鎺変簡杩欎簺鏂囦欢鎻忚堪绗﹀湪绯荤粺璋冪敤鏃跺鍒剁殑寮€閿€銆傚彟涓€涓湰璐ㄧ殑鏀硅繘鍦ㄤ簬epoll閲囩敤鍩轰簬浜嬩欢鐨勫氨缁€氱煡鏂瑰紡銆傚湪select/poll涓紝杩涚▼鍙湁鍦ㄨ皟鐢ㄤ竴瀹氱殑鏂规硶鍚庯紝鍐呮牳鎵嶅鎵€鏈夌洃瑙嗙殑鏂囦欢鎻忚堪绗﹁繘琛屾壂鎻忥紝鑰宔poll浜嬪厛閫氳繃epoll_ctl()鏉ユ敞鍐屼竴涓枃浠舵弿杩扮锛屼竴鏃﹀熀浜庢煇涓枃浠舵弿杩扮灏辩华鏃讹紝鍐呮牳浼氶噰鐢ㄧ被浼糲allback鐨勫洖璋冩満鍒讹紝杩呴€熸縺娲昏繖涓枃浠舵弿杩扮锛屽綋杩涚▼璋冪敤epoll_wait()鏃朵究寰楀埌閫氱煡銆?
 

epoll鏃㈢劧鏄select鍜宲oll鐨勬敼杩涳紝灏卞簲璇ヨ兘閬垮厤涓婅堪鐨勪笁涓己鐐广€傞偅epoll閮芥槸鎬庝箞瑙e喅鐨勫憿锛熷湪姝や箣鍓嶏紝鎴戜滑鍏堢湅涓€涓媏poll 鍜宻elect鍜宲oll鐨勮皟鐢ㄦ帴鍙d笂鐨勪笉鍚岋紝select鍜宲oll閮藉彧鎻愪緵浜嗕竴涓嚱鏁扳€斺€攕elect鎴栬€卲oll鍑芥暟銆傝€宔poll鎻愪緵浜嗕笁涓嚱 鏁帮紝epoll_create,epoll_ctl鍜宔poll_wait锛宔poll_create鏄垱寤轰竴涓猠poll鍙ユ焺锛沞poll_ctl鏄敞 鍐岃鐩戝惉鐨勪簨浠剁被鍨嬶紱epoll_wait鍒欐槸绛夊緟浜嬩欢鐨勪骇鐢熴€?
銆€銆€瀵逛簬绗竴涓己鐐癸紝epoll鐨勮В鍐虫柟妗堝湪epoll_ctl鍑芥暟涓€傛瘡娆℃敞鍐屾柊鐨勪簨浠跺埌epoll鍙ユ焺涓椂锛堝湪epoll_ctl涓寚瀹?EPOLL_CTL_ADD锛夛紝浼氭妸鎵€鏈夌殑fd鎷疯礉杩涘唴鏍革紝鑰屼笉鏄湪epoll_wait鐨勬椂鍊欓噸澶嶆嫹璐濄€俥poll淇濊瘉浜嗘瘡涓猣d鍦ㄦ暣涓繃绋嬩腑鍙細鎷疯礉 涓€娆°€?
銆€銆€瀵逛簬绗簩涓己鐐癸紝epoll鐨勮В鍐虫柟妗堜笉鍍弒elect鎴杙oll涓€鏍锋瘡娆¢兘鎶奵urrent杞祦鍔犲叆fd瀵瑰簲鐨勮澶囩瓑寰呴槦鍒椾腑锛岃€屽彧鍦?epoll_ctl鏃舵妸current鎸備竴閬嶏紙杩欎竴閬嶅繀涓嶅彲灏戯級骞朵负姣忎釜fd鎸囧畾涓€涓洖璋冨嚱鏁帮紝褰撹澶囧氨缁紝鍞ら啋绛夊緟闃熷垪涓婄殑绛夊緟鑰呮椂锛屽氨浼氳皟鐢ㄨ繖涓洖璋?鍑芥暟锛岃€岃繖涓洖璋冨嚱鏁颁細鎶婂氨缁殑fd鍔犲叆涓€涓氨缁摼琛級銆俥poll_wait鐨勫伐浣滃疄闄呬笂灏辨槸鍦ㄨ繖涓氨缁摼琛ㄤ腑鏌ョ湅鏈夋病鏈夊氨缁殑fd锛堝埄鐢?schedule_timeout()瀹炵幇鐫′竴浼氾紝鍒ゆ柇涓€浼氱殑鏁堟灉锛屽拰select瀹炵幇涓殑绗?姝ユ槸绫讳技鐨勶級銆?
銆€銆€瀵逛簬绗笁涓己鐐癸紝epoll娌℃湁杩欎釜闄愬埗锛屽畠鎵€鏀寔鐨凢D涓婇檺鏄渶澶у彲浠ユ墦寮€鏂囦欢鐨勬暟鐩紝杩欎釜鏁板瓧涓€鑸繙澶т簬2048,涓句釜渚嬪瓙, 鍦?GB鍐呭瓨鐨勬満鍣ㄤ笂澶х害鏄?0涓囧乏鍙筹紝鍏蜂綋鏁扮洰鍙互cat /proc/sys/fs/file-max瀵熺湅,涓€鑸潵璇磋繖涓暟鐩拰绯荤粺鍐呭瓨鍏崇郴寰堝ぇ銆?
鎬荤粨锛?
锛?/span>1锛塻elect锛宲oll瀹炵幇闇€瑕佽嚜宸变笉鏂疆璇㈡墍鏈塮d闆嗗悎锛岀洿鍒拌澶囧氨缁紝鏈熼棿鍙兘瑕佺潯鐪犲拰鍞ら啋澶氭浜ゆ浛銆傝€宔poll鍏跺疄涔熼渶瑕佽皟鐢?epoll_wait涓嶆柇杞灏辩华閾捐〃锛屾湡闂翠篃鍙兘澶氭鐫$湢鍜屽敜閱掍氦鏇匡紝浣嗘槸瀹冩槸璁惧灏辩华鏃讹紝璋冪敤鍥炶皟鍑芥暟锛屾妸灏辩华fd鏀惧叆灏辩华閾捐〃涓紝骞跺敜閱掑湪 epoll_wait涓繘鍏ョ潯鐪犵殑杩涚▼銆傝櫧鐒堕兘瑕佺潯鐪犲拰浜ゆ浛锛屼絾鏄痵elect鍜宲oll鍦ㄢ€滈啋鐫€鈥濈殑鏃跺€欒閬嶅巻鏁翠釜fd闆嗗悎锛岃€宔poll鍦ㄢ€滈啋鐫€鈥濈殑 鏃跺€欏彧瑕佸垽鏂竴涓嬪氨缁摼琛ㄦ槸鍚︿负绌哄氨琛屼簡锛岃繖鑺傜渷浜嗗ぇ閲忕殑CPU鏃堕棿锛岃繖灏辨槸鍥炶皟鏈哄埗甯︽潵鐨勬€ц兘鎻愬崌銆?
锛?/span>2锛塻elect锛宲oll姣忔璋冪敤閮借鎶奻d闆嗗悎浠庣敤鎴锋€佸線鍐呮牳鎬佹嫹璐濅竴娆★紝骞朵笖瑕佹妸current寰€璁惧绛夊緟闃熷垪涓寕涓€娆★紝鑰宔poll鍙 涓€娆℃嫹璐濓紝鑰屼笖鎶奵urrent寰€绛夊緟闃熷垪涓婃寕涔熷彧鎸備竴娆★紙鍦╡poll_wait鐨勫紑濮嬶紝娉ㄦ剰杩欓噷鐨勭瓑寰呴槦鍒楀苟涓嶆槸璁惧绛夊緟闃熷垪锛屽彧鏄竴涓猠poll鍐?閮ㄥ畾涔夌殑绛夊緟闃熷垪锛夛紝杩欎篃鑳借妭鐪佷笉灏戠殑寮€閿€銆?
select,poll,epoll
select锛宲oll锛宔poll

銆€銆€杩欎笁绉岻O澶氳矾澶嶇敤妯″瀷鍦ㄤ笉鍚岀殑骞冲彴鏈夌潃涓嶅悓鐨勬敮鎸侊紝鑰宔poll鍦╳indows涓嬪氨涓嶆敮鎸侊紝濂藉湪鎴戜滑鏈塻electors妯″潡锛屽府鎴戜滑榛樿閫夋嫨褰撳墠骞冲彴涓嬫渶鍚堥€傜殑锛屾垜浠彧闇€瑕佸啓鐩戝惉璋侊紝鐒跺悗鎬庝箞鍙戦€佹秷鎭帴鏀舵秷鎭紝浣嗘槸鍏蜂綋鎬庝箞鐩戝惉鐨勶紝閫夋嫨鐨勬槸select杩樻槸poll杩樻槸epoll锛岃繖鏄痵elector甯垜浠嚜鍔ㄩ€夋嫨鐨勩€?/p>

鎶€鏈垎浜浘鐗? id=
#鏈嶅姟绔?/span>
from socket import *
import selectors

sel=selectors.DefaultSelector()
def accept(server_fileobj,mask):
    conn,addr=server_fileobj.accept()
    sel.register(conn,selectors.EVENT_READ,read)

def read(conn,mask):
    try:
        data=conn.recv(1024)
        if not data:
            print(鈥?/span>closing鈥?/span>,conn)
            sel.unregister(conn)
            conn.close()
            return
        conn.send(data.upper()+b鈥?/span>_SB鈥?/span>)
    except Exception:
        print(鈥?/span>closing鈥?/span>, conn)
        sel.unregister(conn)
        conn.close()



server_fileobj=socket(AF_INET,SOCK_STREAM)
server_fileobj.setsockopt(SOL_SOCKET,SO_REUSEADDR,1)
server_fileobj.bind((鈥?/span>127.0.0.1鈥?/span>,8088))
server_fileobj.listen(5)
server_fileobj.setblocking(False) #璁剧疆socket鐨勬帴鍙d负闈為樆濉?/span>
sel.register(server_fileobj,selectors.EVENT_READ,accept) #鐩稿綋浜庣綉select鐨勮鍒楄〃閲宎ppend浜嗕竴涓枃浠跺彞鏌剆erver_fileobj,骞朵笖缁戝畾浜嗕竴涓洖璋冨嚱鏁癮ccept

while True:
    events=sel.select() #妫€娴嬫墍鏈夌殑fileobj锛屾槸鍚︽湁瀹屾垚wait data鐨?/span>
    for sel_obj,mask in events:
        callback=sel_obj.data #callback=accpet
        callback(sel_obj.fileobj,mask) #accpet(server_fileobj,1)

#瀹㈡埛绔?/span>
from socket import *
c=socket(AF_INET,SOCK_STREAM)
c.connect((鈥?/span>127.0.0.1鈥?/span>,8088))

while True:
    msg=input(鈥?/span>>>: 鈥?/span>)
    if not msg:continue
    c.send(msg.encode(鈥?/span>utf-8鈥?/span>))
    data=c.recv(1024)
    print(data.decode(鈥?/span>utf-8鈥?/span>))

selector浠g爜绀轰緥
selectors

 








以上是关于IO澶氳矾澶嶇敤的主要内容,如果未能解决你的问题,请参考以下文章

HTTP/3 鏉ヤ簡 !

HTTP/3灞曟湜

V-for灏卞湴澶嶇敤鍘熺悊銆佽櫄鎷烡OM銆丏iff绠楁硶锛?/a>

Java瀛︿範绗旇1

java内存流:java.io.ByteArrayInputStreamjava.io.ByteArrayOutputStreamjava.io.CharArrayReaderjava.io(代码片段

java缓冲字符字节输入输出流:java.io.BufferedReaderjava.io.BufferedWriterjava.io.BufferedInputStreamjava.io.(代码片段