锘??xml version="1.0" encoding="utf-8" standalone="yes"?>
1. 闈?rùn)鎬佸嚱鏁板簱
榪欑被搴撶殑鍚嶅瓧涓鑸槸libxxx.a錛涘埄鐢ㄩ潤(rùn)鎬佸嚱鏁板簱緙栬瘧鎴愮殑鏂囦歡姣旇緝澶э紝鍥犱負(fù)鏁翠釜 鍑芥暟搴撶殑鎵鏈夋暟鎹兘浼?xì)琚暣鍚垬q涚洰鏍囦唬鐮佷腑錛屼粬鐨勪紭鐐瑰氨鏄捐屾槗瑙佷簡(jiǎn)錛屽嵆緙栬瘧鍚庣殑鎵ц紼嬪簭涓嶉渶瑕佸閮ㄧ殑鍑芥暟搴撴敮鎸侊紝鍥犱負(fù)鎵鏈変嬌鐢ㄧ殑鍑芥暟閮藉凡緇忚緙栬瘧榪涘幓浜?jiǎn)銆傚綋鐒惰繖涔熶細(xì)鎴愪負(fù)浠栫殑緙虹偣錛屽洜涓哄鏋滈潤(rùn)鎬佸嚱鏁板簱鏀瑰彉浜?jiǎn)锛岄偅涔堜綘鐨劷E嬪簭蹇呴』閲嶆柊緙栬瘧銆?/p>
2. 鍔ㄦ佸嚱鏁板簱
榪欑被搴撶殑鍚嶅瓧涓鑸槸libxxx.so;鐩稿浜庨潤(rùn)鎬佸嚱鏁板簱錛屽姩鎬佸嚱鏁板簱鍦ㄧ紪璇戠殑鏃跺?騫舵病鏈夎緙栬瘧榪涚洰鏍囦唬鐮佷腑錛屼綘鐨勭▼搴忔墽琛屽埌鐩稿叧鍑芥暟鏃舵墠璋冪敤璇ュ嚱鏁板簱閲岀殑鐩稿簲鍑芥暟錛屽洜姝ゅ姩鎬佸嚱鏁板簱鎵浜х敓鐨勫彲鎵ц鏂囦歡姣旇緝?yōu)畯銆傜敱浜庡嚱鏁板簱娌℃湁琚暣鍚堣繘浣犵殑紼嬪簭錛岃屾槸紼嬪簭榪愯鏃跺姩鎬佺殑鐢寵騫惰皟鐢紝鎵浠ョ▼搴忕殑榪愯鐜涓繀欏繪彁渚涚浉搴旂殑搴撱傚姩鎬佸嚱鏁板簱鐨勬敼鍙樺茍涓嶅獎(jiǎng)鍝嶄綘鐨勭▼搴忥紝鎵浠ュ姩鎬佸嚱鏁板簱鐨勫崌綰ф瘮杈冩柟渚褲?nbsp;
linux緋葷粺鏈夊嚑涓噸瑕佺殑鐩綍瀛樻斁鐩稿簲鐨勫嚱鏁板簱錛屽/lib /usr/lib銆?/p>
闈?rùn)鎬佸簱鐨勬搷浣滃伐鍏鳳細(xì)gcc鍜宎r 鍛戒護(hù)銆?nbsp;
緙栧啓鍙?qiáng)鋴社敤闈?rùn)鎬佸簱
(1)璁捐搴撴簮鐮?pr1.c 鍜?pr2.c
[root@billstone make_lib]# cat pr1.c
void print1()
{
printf("This is the first lib src!\n");
}
[root@billstone make_lib]# cat pr2.c
void print2()
{
printf("This is the second src lib!\n");
}
(2) 緙栬瘧.c 鏂囦歡
[bill@billstone make_lib]$ cc -O -c pr1.c pr2.c
[bill@billstone make_lib]$ ls -l pr*.o
-rw-rw-r-- 1 bill bill 804 4 鏈?nbsp; 15 11:11 pr1.o
-rw-rw-r-- 1 bill bill 804 4 鏈?nbsp; 15 11:11 pr2.o
(3) 閾炬帴闈?rùn)鎬佸簱
涓轟簡(jiǎn)鍦ㄧ紪璇戠▼搴忎腑姝g‘鎵懼埌搴撴枃浠?闈?rùn)鎬佸簱蹇呴』鎸夌収 lib[name].a 鐨勮鍒欏懡鍚?濡備笅渚嬩腑[name]=pr.
[bill@billstone make_lib]$ ar -rsv libpr.a pr1.o pr2.o
a - pr1.o
a - pr2.o
[bill@billstone make_lib]$ ls -l *.a
-rw-rw-r-- 1 bill bill 1822 4 鏈?nbsp; 15 11:12 libpr.a
[bill@billstone make_lib]$ ar -t libpr.a
pr1.o
pr2.o
(4) 璋冪敤搴撳嚱鏁頒唬鐮?main.c
[bill@billstone make_lib]$ cat main.c
int main()
{
print1();
print2();
return 0;
}
(5) 緙栬瘧閾炬帴閫夐」
-L 鍙?l 鍙傛暟鏀懼湪鍚庨潰.鍏朵腑,-L 鍔犺澆搴撴枃浠惰礬寰?-l 鎸囨槑搴撴枃浠跺悕瀛?
[bill@billstone make_lib]$ gcc -o main main.c -L./ -lpr
[bill@billstone make_lib]$ ls -l main*
-rwxrwxr-x 1 bill bill 11805 4 鏈?nbsp; 15 11:17 main
-rw-rw-r-- 1 bill bill 50 4 鏈?nbsp; 15 11:15 main.c
(6)鎵ц鐩爣紼嬪簭
[bill@billstone make_lib]$ ./main
This is the first lib src!
This is the second src lib!
[bill@billstone make_lib]$
緙栧啓鍔ㄦ佸簱
(1)璁捐搴撲唬鐮?/strong>
[bill@billstone make_lib]$ cat pr1.c
int p = 2;
void print(){
printf("This is the first dll src!\n");
}
[bill@billstone make_lib]$
(2)鐢熸垚鍔ㄦ佸簱
[bill@billstone make_lib]$ gcc -O -fpic -shared -o dl.so pr1.c
[bill@billstone make_lib]$ ls -l *.so
-rwxrwxr-x 1 bill bill 6592 4 鏈?nbsp; 15 15:19 dl.so
[bill@billstone make_lib]$
鍔ㄦ佸簱鐨勯殣寮忚皟鐢?/strong>
鍦ㄧ紪璇戣皟鐢ㄥ簱鍑芥暟浠g爜鏃舵寚鏄庡姩鎬佸簱鐨勪綅緗強(qiáng)鍚嶅瓧, 鐪嬩笅闈㈠疄渚?nbsp;
[bill@billstone make_lib]$ cat main.c
int main()
{
print();
return 0;
}
[bill@billstone make_lib]$ gcc -o tdl main.c ./dl.so
[bill@billstone make_lib]$ ./tdl
This is the first dll src!
[bill@billstone make_lib]$
褰撳姩鎬佸簱鐨勪綅緗椿鍚嶅瓧鍙戠敓鏀瑰彉鏃? 紼嬪簭灝嗘棤娉曟甯歌繍琛? 鑰屽姩鎬佸簱鍙栦唬闈?rùn)鎬佸簱鐨勫ソ澶勪箣涓鍒欐槸閫氳繃鏇存柊鍔ㄦ佸簱鑰岄殢鏃跺崌綰у簱鐨勫唴瀹?
鍔ㄦ佸簱鐨勬樉寮忚皟鐢?/strong>
鏄懼紡璋冪敤鍔ㄦ佸簱闇瑕佸洓涓嚱鏁扮殑鏀寔, 鍑芥暟 dlopen 鎵撳紑鍔ㄦ佸簱, 鍑芥暟 dlsym 鑾峰彇鍔ㄦ佸簱涓璞″熀鍧, 鍑?/strong>鏁?dlerror 鑾峰彇鏄懼紡鍔ㄦ佸簱鎿嶄綔涓殑閿欒淇℃伅, 鍑芥暟 doclose 鍏抽棴鍔ㄦ佸簱.
[bill@billstone make_lib]$ cat main.c
#include <dlfcn.h>
int main()
{
void *pHandle;
void (*pFunc)(); // 鎸囧悜鍑芥暟鐨勬寚閽?nbsp;
int *p;
pHandle = dlopen("./d1.so", RTLD_NOW); // 鎵撳紑鍔ㄦ佸簱
if(!pHandle){
printf("Can't find d1.so \n");
exit(1);
}
pFunc = (void (*)())dlsym(pHandle, "print"); // 鑾峰彇搴撳嚱鏁?print 鐨勫湴鍧
if(pFunc)
pFunc();
else
printf("Can't find function print\n");
p = (int *)dlsym(pHandle, "p"); // 鑾峰彇搴撳彉閲?p 鐨勫湴鍧
if(p)
printf("p = %d\n", *p);
else
printf("Can't find int p\n");
dlclose(pHandle); // 鍏抽棴鍔ㄦ佸簱
return 0;
}
[bill@billstone make_lib]$ gcc -o tds main.c –ld1 –L.
姝ゆ椂榪樹笉鑳界珛鍗?/tds錛屽洜涓哄湪鍔ㄦ佸嚱鏁板簱浣跨敤鏃訛紝浼?xì)鏌ユ?usr/lib銆?lib鐩綍涓嬬殑鍔ㄦ佸嚱鏁板簱錛岃屾鏃舵垜浠敓鎴愮殑搴撲笉鍦ㄩ噷杈廣?榪欎釜鏃跺欐湁濂藉嚑縐嶆柟娉曞彲浠ヨ浠栨垚鍔熻繍琛岋細(xì) 鏈鐩存帴鏈綆鍗曠殑鏂規(guī)硶灝辨槸鎶妉ibstr_out.so鎷夊埌/usr/lib鎴?lib涓幓銆?榪樻湁涓縐嶆柟娉?export LD_LIBRARY_PATH=$(pwd) 鍙﹀榪樺彲浠ュ湪/etc/ld.so.conf鏂囦歡閲屽姞鍏ユ垜浠敓鎴愮殑搴撶殑鐩綍錛岀劧鍚?sbin/ldconfig銆?/etc/ld.so.conf鏄潪甯擱噸瑕佺殑涓涓洰褰曪紝閲岄潰瀛樻斁鐨勬槸閾炬帴鍣ㄥ拰鍔犺澆鍣ㄦ悳绱㈠叡浜簱鏃惰媯(gè)鏌ョ殑鐩綍錛岄粯璁ゆ槸浠?usr/lib /lib涓鍙栫殑錛屾墍浠ユ兂瑕侀『鍒╄繍琛岋紝鎴戜滑涔熷彲浠ユ妸鎴戜滑搴撶殑鐩綍鍔犲叆鍒拌繖涓枃浠朵腑騫舵墽琛?sbin/ldconfig 銆傚彟澶栬繕鏈変釜鏂囦歡闇瑕佷簡(jiǎn)瑙?etc/ld.so.cache,閲岄潰淇濆瓨浜?jiǎn)甯哥敤鐨勫姩鎬佸嚱鏁板簱錛屼笖浼?xì)鍏堟妸浠栦滑鍔犺浇鍒板唴瀛樹腑锛屽洜湄?fù)鍐呭瓨鐨勮闂熷害榪滆繙澶т簬紜洏鐨勮闂熷害錛岃繖鏍峰彲浠ユ彁楂樿蔣浠跺姞杞藉姩鎬佸嚱鏁板簱鐨勯熷害浜?jiǎn)銆?/p>
浣跨敤ldd鍛戒護(hù)鏉ユ煡鐪嬫墽琛屾枃浠朵緷璧栦簬鍝簺搴撱?/p>
璇ュ懡浠ょ敤浜庡垽鏂煇涓彲鎵ц鐨?binary 妗f鍚湁浠涔堝姩鎬佸嚱寮忓簱銆?br />
[root@test root]# ldd [-vdr] [filename]
鍙傛暟璇存槑錛?br />
--version銆銆鎵撳嵃l(fā)dd鐨勭増鏈彿
-v --verbose銆銆鎵撳嵃鎵鏈変俊鎭紝渚嬪鍖呮嫭絎﹀彿鐨勭増鏈俊鎭?br />
-d --data-relocs銆銆鎵ц絎﹀彿閲嶉儴緗詫紝騫舵姤鍛婄己灝戠殑鐩爣瀵硅薄錛堝彧瀵笶LF鏍煎紡閫傜敤錛?br />
-r --function-relocs銆銆瀵圭洰鏍囧璞″拰鍑芥暟鎵ц閲嶆柊閮ㄧ講錛屽茍鎶ュ憡緙哄皯鐨勭洰鏍囧璞″拰鍑芥暟錛堝彧瀵笶LF鏍煎紡閫傜敤錛?br />
--help 鐢ㄦ硶淇℃伅銆?/p>
濡傛灉鍛戒護(hù)琛屼腑緇欏畾鐨勫簱鍚嶅瓧鍖呭惈'/'錛岃繖涓▼搴忕殑libc5鐗堟湰灝嗕嬌鐢ㄥ畠浣滀負(fù)搴撳悕瀛楋紱鍚﹀垯瀹冨皢鍦ㄦ爣鍑嗕綅緗悳绱㈠簱銆傝繍琛屼竴涓綋鍓嶇洰褰曚笅鐨勫叡浜簱錛屽姞鍓嶇紑"./"銆?/p>
@import url(http://www.shnenglu.com/CuteSoft_Client/CuteEditor/Load.ashx?type=style&file=SyntaxHighlighter.css);@import url(/css/cuteeditor.css);
WINDOWS瀹屾垚绔彛緙栫▼
鎽樿錛氬紑鍙戠綉緇滅▼搴忎粠鏉ラ兘涓嶆槸涓浠跺鏄撶殑浜嬫儏錛屽敖綆″彧闇瑕侀伒瀹堝緢灝戠殑涓浜涜鍒?鍒涘緩socket,鍙戣搗榪炴帴錛屾帴鍙楄繛鎺ワ紝鍙戦佸拰鎺ュ彈鏁版嵁銆傜湡姝g殑鍥伴毦鍦ㄤ簬錛氳浣犵殑紼嬪簭鍙互閫傚簲浠庡崟鍗曚竴涓繛鎺ュ埌鍑犲崈涓繛鎺ヤ箖鑷充簬涓婁竾涓繛鎺ャ傚埄鐢╓indows騫沖彴瀹屾垚绔彛榪涜閲嶅彔I(yíng)/O鐨勬妧鏈拰Linux鍦?.6鐗堟湰鐨勫唴鏍鎬腑寮曞叆鐨?strong>EPOll鎶鏈紝鍙互寰堟柟渚垮湪鍦ㄥ湪Windows鍜孡inux騫沖彴涓婂紑鍙戝嚭鏀寔澶ч噺榪炴帴鐨勭綉緇滄湇鍔$▼搴忋傛湰鏂囦粙緇嶅湪Windows鍜孡inux騫沖彴涓婁嬌鐢ㄧ殑瀹屾垚绔彛鍜?strong>EPoll妯″瀷寮鍙戠殑鍩烘湰鍘熺悊錛屽悓鏃剁粰鍑哄疄闄呯殑渚嬪瓙銆傛湰鏂囦富瑕佸叧娉–/S緇撴瀯鐨勬湇鍔″櫒绔▼搴忥紝鍥犱負(fù)涓鑸潵璇達(dá)紝寮鍙戜竴涓ぇ瀹歸噺錛屽叿鍙墿灞曟х殑winsock紼嬪簭涓鑸氨鏄寚鏈嶅姟紼嬪簭銆?br />
1銆佸熀鏈蹇?br />
璁懼---windows鎿嶄綔緋葷粺涓婂厑璁?dāng)R氫俊鐨勪換浣曚笢瑗匡紝姣斿鏂囦歡銆佺洰褰曘佷覆琛屽彛銆佸茍琛屽彛銆侀偖浠舵Ы銆佸懡鍚嶇閬撱佹棤鍚嶇閬撱佸鎺ュ瓧銆佹帶鍒跺彴銆侀昏緫紓佺洏銆佺墿鐞嗙鐩樼瓑銆傜粷澶у鏁頒笌璁懼鎵撲氦閬撶殑鍑芥暟閮芥槸CreateFile/ReadFile/WriteFile絳夈傛墍浠ユ垜浠笉鑳界湅鍒?*File鍑芥暟灝卞彧鎯沖埌鏂囦歡璁懼銆備笌璁懼閫氫俊鏈変袱縐嶆柟寮忥紝鍚屾鏂瑰紡鍜屽紓姝ユ柟寮忋傚悓姝ユ柟寮忎笅錛屽綋璋冪敤ReadFile鍑芥暟鏃訛紝鍑芥暟浼?xì)绛夊緟绯痪l熸墽琛屽畬鎵瑕佹眰鐨勫伐浣滐紝鐒跺悗鎵嶈繑鍥烇紱寮傛鏂瑰紡涓嬶紝ReadFile榪欑被鍑芥暟浼?xì)鐩存帴杩斿洖锛尵p葷粺鑷繁鍘誨畬鎴愬璁懼鐨勬搷浣滐紝鐒跺悗浠ユ煇縐嶆柟寮忛氱煡瀹屾垚鎿嶄綔銆?br />
閲嶅彔I(yíng)/O----欏懼悕鎬濅箟錛屽綋浣犺皟鐢ㄤ簡(jiǎn)鏌愪釜鍑芥暟錛堟瘮濡俁eadFile錛夊氨绔嬪埢榪斿洖鍋氳嚜宸辯殑鍏朵粬鍔ㄤ綔鐨勬椂鍊欙紝鍚屾椂緋葷粺涔熷湪瀵笽/0璁懼榪涜浣犺姹傜殑鎿嶄綔錛屽湪榪欐鏃墮棿鍐呬綘鐨勭▼搴忓拰緋葷粺鐨勫唴閮ㄥ姩浣滄槸閲嶅彔鐨勶紝鍥犳鏈夋洿濂界殑鎬ц兘銆傛墍浠ワ紝閲嶅彔I(yíng)/O鏄敤浜庡紓姝ユ柟寮忎笅浣跨敤I/O璁懼鐨勩?閲嶅彔I(yíng)/O闇瑕佷嬌鐢ㄧ殑涓涓潪甯擱噸瑕佺殑鏁版嵁緇撴瀯OVERLAPPED銆?br />
2銆乄INDOWS瀹屾垚绔彛鐨勭壒鐐?br />
Win32閲嶅彔I(yíng)/O(Overlapped I/O)鏈哄埗鍏佽鍙戣搗涓涓搷浣滐紝鐒跺悗鍦ㄦ搷浣滃畬鎴愪箣鍚庢帴鍙楀埌淇℃伅銆傚浜庨偅縐嶉渶瑕佸緢闀挎椂闂存墠鑳藉畬鎴愮殑鎿嶄綔鏉ヨ錛岄噸鍙營(yíng)O鏈哄埗灝ゅ叾鏈夌敤錛屽洜涓哄彂璧烽噸鍙犳搷浣滅殑綰跨▼鍦ㄩ噸鍙犺姹傚彂鍑哄悗灝卞彲浠ヨ嚜鐢辯殑鍋氬埆鐨勪簨鎯呬簡(jiǎn)銆傚湪WinNT鍜學(xué)in2000涓婏紝鎻愪緵鐨勭湡姝g殑鍙墿灞曠殑I/O妯″瀷灝辨槸浣跨敤瀹屾垚绔彛錛圕ompletion Port錛夌殑閲嶅彔I(yíng)/O.瀹屾垚绔彛---鏄竴縐峎INDOWS鍐呮牳瀵硅薄銆?strong>瀹屾垚绔彛鐢ㄤ簬寮傛鏂瑰紡鐨勯噸鍙營(yíng)/0鎯呭喌涓嬶紝褰撶劧閲嶅彔I(yíng)/O涓嶄竴瀹氶潪浣跨敤瀹屾垚绔彛涓嶅彲錛岃繕鏈夎澶囧唴鏍稿璞°佷簨浠跺璞°佸憡璀/0絳夈備絾鏄?strong>瀹屾垚绔彛鍐呴儴鎻愪緵浜?jiǎn)绾拷E嬫睜鐨勭鐞嗭紝鍙互閬垮厤鍙嶅鍒涘緩綰跨▼鐨勫紑閿錛屽悓鏃跺彲浠ユ牴鎹瓹PU鐨勪釜鏁扮伒媧葷殑鍐沖畾綰跨▼涓暟錛岃屼笖鍙互璁╁噺灝戠嚎紼嬭皟搴︾殑嬈℃暟浠庤屾彁楂樻ц兘鍏跺疄綾諱技浜嶹SAAsyncSelect鍜宻elect鍑芥暟鐨勬満鍒舵洿瀹規(guī)槗鍏煎Unix錛屼絾鏄毦浠ュ疄鐜版垜浠兂瑕佺殑“鎵╁睍鎬?#8221;銆傝屼笖windows鐨?strong>瀹屾垚绔彛鏈哄埗鍦ㄦ搷浣滅郴緇熷唴閮ㄥ凡緇忎綔浜?jiǎn)浼樺寲锛屾彁渚涗簡(jiǎn)鏇撮珮鐨勬晥鐜囥傛墍浠ワ紝鎴戜滑閫夋嫨瀹屾垚绔彛寮濮嬫垜浠殑鏈嶅姟鍣ㄧ▼搴忕殑寮鍙戙?br />
1銆佸彂璧鋒搷浣滀笉涓瀹氬畬鎴愶紝緋葷粺浼?xì)鍦ㄥ畬鎴愮殑鏃跺欓氱煡浣狅紝閫氳繃鐢ㄦ埛鍦?strong>瀹屾垚绔彛涓婄殑絳夊緟錛屽鐞嗘搷浣滅殑緇撴灉銆傛墍浠ヨ鏈夋鏌?strong>瀹屾垚绔彛錛屽彇鎿嶄綔緇撴灉鐨勭嚎紼嬨傚湪瀹屾垚绔彛涓婂畧鍊欑殑綰跨▼緋葷粺鏈変紭鍖栵紝闄ら潪鍦ㄦ墽琛岀殑綰跨▼闃誨錛屼笉浼?xì)鏈夋柊鐨劸U跨▼琚縺媧伙紝浠ユ鏉ュ噺灝戠嚎紼嬪垏鎹㈤犳垚鐨勬ц兘浠d環(huán)銆傛墍浠ュ鏋滅▼搴忎腑娌℃湁澶鐨勯樆濉炴搷浣滐紝娌℃湁蹇呰鍚姩澶鐨勭嚎紼嬶紝CPU鏁伴噺鐨勪袱鍊嶏紝涓鑸繖鏍鋒潵鍚姩綰跨▼銆?br />
2銆佹搷浣滀笌鐩稿叧鏁版嵁鐨勭粦瀹氭柟寮忥細(xì)鍦ㄦ彁浜ゆ暟鎹殑鏃跺欑敤鎴峰鏁版嵁鎵撶浉搴旂殑鏍囪錛岃褰曟搷浣滅殑綾誨瀷錛屽湪鐢ㄦ埛澶勭悊鎿嶄綔緇撴灉鐨勬椂鍊欙紝閫氳繃媯(gè)鏌ヨ嚜宸辨墦鐨勬爣璁板拰緋葷粺鐨勬搷浣滅粨鏋滆繘琛岀浉搴旂殑澶勭悊銆?nbsp;
3銆佹搷浣滆繑鍥炵殑鏂瑰紡:涓鑸搷浣滃畬鎴愬悗瑕侀氱煡紼嬪簭榪涜鍚庣畫澶勭悊銆備絾鍐欐搷浣滃彲浠ヤ笉閫氱煡鐢ㄦ埛錛屾鏃跺鏋滅敤鎴峰啓鎿嶄綔涓嶈兘椹笂瀹屾垚錛屽啓鎿嶄綔鐨勭浉鍏蟲暟鎹細(xì)琚殏瀛樺埌鍒伴潪浜ゆ崲緙撳啿鍖轟腑錛屽湪鎿嶄綔瀹屾垚鐨勬椂鍊欙紝緋葷粺浼?xì)鑷姩閲婃攧〖撳啿鍖恒傛鏃跺彂璧峰畬鍐欐搷浣滐紝浣跨敤鐨勫唴瀛樺氨鍙互閲婃斁浜?jiǎn)銆傛鏃跺鏋滃崰鐢ㄩ潪浜ゆ崲緙撳啿澶浼?xì)鋴删p葷粺鍋滄鍝嶅簲銆?br />
3銆?strong>瀹屾垚绔彛錛圕ompletion Ports 錛夌浉鍏蟲暟鎹粨鏋勫拰鍒涘緩
鍏跺疄鍙互鎶?strong>瀹屾垚绔彛鐪嬫垚緋葷粺緇存姢鐨勪竴涓槦鍒楋紝鎿嶄綔緋葷粺鎶婇噸鍙營(yíng)O鎿嶄綔瀹屾垚鐨勪簨浠墮氱煡鏀懼埌璇ラ槦鍒楅噷錛岀敱浜庢槸鏆撮湶 “鎿嶄綔瀹屾垚”鐨勪簨浠墮氱煡錛屾墍浠ュ懡鍚嶄負(fù)“瀹屾垚绔彛”錛圕Ompletion Ports錛夈備竴涓猻ocket琚垱寤哄悗錛屽彲浠ュ湪浠諱綍鏃跺埢鍜屼竴涓?strong>瀹屾垚绔彛鑱旂郴璧鋒潵銆?br />
瀹屾垚绔彛鐩稿叧鏈閲嶈鐨勬槸OVERLAPPED鏁版嵁緇撴瀯
typedef struct _OVERLAPPED {
ULONG_PTR Internal;//琚郴緇熷唴閮ㄨ祴鍊鹼紝鐢ㄦ潵琛ㄧず緋葷粺鐘舵?nbsp;
ULONG_PTR InternalHigh;// 琚郴緇熷唴閮ㄨ祴鍊鹼紝浼犺緭鐨勫瓧鑺傛暟
union {
struct {
DWORD Offset;//鍜孫ffsetHigh鍚堟垚涓涓?4浣嶇殑鏁存暟錛岀敤鏉ヨ〃紺轟粠鏂囦歡澶撮儴鐨勫灝戝瓧鑺傚紑濮?nbsp;
DWORD OffsetHigh;//鎿嶄綔錛屽鏋滀笉鏄鏂囦歡I/O鏉ユ搷浣滐紝鍒欏繀欏昏瀹氫負(fù)0
};
PVOID Pointer;
};
HANDLE hEvent;//濡傛灉涓嶄嬌鐢紝灝卞姟蹇呰涓?,鍚﹀垯璇瘋祴涓涓湁鏁堢殑Event鍙ユ焺
} OVERLAPPED, *LPOVERLAPPED;
涓嬮潰鏄紓姝ユ柟寮忎嬌鐢≧eadFile鐨勪竴涓緥瀛?nbsp;
OVERLAPPED Overlapped;
Overlapped.Offset=345;
Overlapped.OffsetHigh=0;
Overlapped.hEvent=0;
//鍋囧畾鍏朵粬鍙傛暟閮藉凡緇忚鍒濆鍖?nbsp;
ReadFile(hFile,buffer,sizeof(buffer),&dwNumBytesRead,&Overlapped);
榪欐牱灝卞畬鎴愪簡(jiǎn)寮傛鏂瑰紡璇繪枃浠剁殑鎿嶄綔錛岀劧鍚嶳eadFile鍑芥暟榪斿洖錛岀敱鎿嶄綔緋葷粺鍋氳嚜宸辯殑浜嬫儏錛屼笅闈粙緇嶅嚑涓笌OVERLAPPED緇撴瀯鐩稿叧鐨勫嚱鏁?nbsp;
絳夊緟閲嶅彔I(yíng)/0鎿嶄綔瀹屾垚鐨勫嚱鏁?nbsp;
BOOL GetOverlappedResult (
HANDLE hFile,
LPOVERLAPPED lpOverlapped,//鎺ュ彈榪斿洖鐨勯噸鍙營(yíng)/0緇撴瀯
LPDWORD lpcbTransfer,//鎴愬姛浼犺緭浜?jiǎn)澶殲畱瀛楄妭鏁?br />
BOOL fWait //TRUE鍙湁褰撴搷浣滃畬鎴愭墠榪斿洖錛孎ALSE鐩存帴榪斿洖錛屽鏋滄搷浣滄病鏈夊畬鎴愶紝閫氳繃璋?/鐢℅etLastError ( )鍑芥暟浼?xì)杩斿洖ERROR_IO_INCOMPLETE
);
瀹廐asOverlappedIoCompleted鍙互甯姪鎴戜滑嫻嬭瘯閲嶅彔I(yíng)/0鎿嶄綔鏄惁瀹屾垚錛岃瀹忓OVERLAPPED緇撴瀯鐨処nternal鎴愬憳榪涜浜?jiǎn)娴嬭瘯锛屾煡鐪嬫槸鍚{変簬STATUS_PENDING鍊箋?/p>
涓鑸潵璇達(dá)紝涓涓簲鐢ㄧ▼搴忓彲浠ュ垱寤哄涓伐浣滅嚎紼嬫潵澶勭悊瀹屾垚绔彛涓婄殑閫氱煡浜嬩歡銆傚伐浣滅嚎紼嬬殑鏁伴噺渚濊禆浜庣▼搴忕殑鍏蜂綋闇瑕併備絾鏄湪鐞嗘兂鐨勬儏鍐典笅錛屽簲璇ュ搴斾竴涓狢PU鍒涘緩涓涓嚎紼嬨傚洜涓哄湪瀹屾垚绔彛鐞嗘兂妯″瀷涓紝姣忎釜綰跨▼閮藉彲浠ヤ粠緋葷粺鑾峰緱涓涓?#8220;鍘熷瓙”鎬х殑鏃墮棿鐗囷紝杞暘榪愯騫舵鏌?strong>瀹屾垚绔彛錛岀嚎紼嬬殑鍒囨崲鏄澶栫殑寮閿銆傚湪瀹為檯寮鍙戠殑鏃跺欙紝榪樿鑰冭檻榪欎簺綰跨▼鏄惁鐗墊秹鍒板叾浠栧牭濉炴搷浣滅殑鎯呭喌銆傚鏋滄煇綰跨▼榪涜鍫靛鎿嶄綔錛岀郴緇熷垯灝嗗叾鎸傝搗錛岃鍒殑綰跨▼鑾峰緱榪愯鏃墮棿銆傚洜姝わ紝濡傛灉鏈夎繖鏍風(fēng)殑鎯呭喌錛屽彲浠ュ鍒涘緩鍑犱釜綰跨▼鏉ュ敖閲忓埄鐢ㄦ椂闂淬?br />
搴旂敤瀹屾垚绔彛錛?br />
鍒涘緩瀹屾垚绔彛錛?strong>瀹屾垚绔彛鏄竴涓唴鏍稿璞★紝浣跨敤鏃朵粬鎬繪槸瑕佸拰鑷沖皯涓涓湁鏁堢殑璁懼鍙ユ焺榪涜鍏寵仈錛?strong>瀹屾垚绔彛鏄竴涓鏉傜殑鍐呮牳瀵硅薄錛屽垱寤哄畠鐨勫嚱鏁版槸錛?br />
HANDLE CreateIoCompletionPort(
IN HANDLE FileHandle,
IN HANDLE ExistingCompletionPort,
IN ULONG_PTR CompletionKey,
IN DWORD NumberOfConcurrentThreads
);
閫氬父鍒涘緩宸ヤ綔鍒嗕袱姝ワ細(xì)
絎竴姝ワ紝鍒涘緩涓涓柊鐨?strong>瀹屾垚绔彛鍐呮牳瀵硅薄錛屽彲浠ヤ嬌鐢ㄤ笅闈㈢殑鍑芥暟錛?br />
HANDLE CreateNewCompletionPort(DWORD dwNumberOfThreads)
{
return CreateIoCompletionPort(INVALID_HANDLE_VALUE,NULL,NULL,dwNumberOfThreads);
};
絎簩姝ワ紝灝嗗垰鍒涘緩鐨?strong>瀹屾垚绔彛鍜屼竴涓湁鏁堢殑璁懼鍙ユ焺鍏寵仈璧鋒潵錛屽彲浠ヤ嬌鐢ㄤ笅闈㈢殑鍑芥暟錛?br />
bool AssicoateDeviceWithCompletionPort(HANDLE hCompPort,HANDLE hDevice,DWORD dwCompKey)
{
HANDLE h=CreateIoCompletionPort(hDevice,hCompPort,dwCompKey,0);
return h==hCompPort;
};
璇存槑
1錛?CreateIoCompletionPort鍑芥暟涔熷彲浠ヤ竴嬈℃х殑鏃㈠垱寤?strong>瀹屾垚绔彛瀵硅薄錛屽張鍏寵仈鍒頒竴涓湁鏁堢殑璁懼鍙ユ焺
2錛?CompletionKey鏄竴涓彲浠ヨ嚜宸卞畾涔夌殑鍙傛暟錛屾垜浠彲浠ユ妸涓涓粨鏋勭殑鍦板潃璧嬬粰瀹冿紝鐒跺悗鍦ㄥ悎閫傜殑鏃跺欏彇鍑烘潵浣跨敤錛屾渶濂借淇濊瘉緇撴瀯閲岄潰鐨勫唴瀛樹笉鏄垎閰嶅湪鏍堜笂錛岄櫎闈炰綘鏈夊崄鍒嗙殑鎶婃彙鍐呭瓨浼?xì)淇濈暀鍒颁綘瑕佷娇鐢ㄧ殑閭d竴鍒匯?br />
3錛?NumberOfConcurrentThreads閫氬父鐢ㄦ潵鎸囧畾瑕佸厑璁稿悓鏃惰繍琛岀殑鐨勭嚎紼嬬殑鏈澶т釜鏁般傞氬父鎴戜滑鎸囧畾涓?錛岃繖鏍風(fēng)郴緇熶細(xì)鏍規(guī)嵁CPU鐨勪釜鏁版潵鑷姩紜畾銆傚垱寤哄拰鍏寵仈鐨勫姩浣滃畬鎴愬悗錛岀郴緇熶細(xì)灝?strong>瀹屾垚绔彛鍏寵仈鐨勮澶囧彞鏌勩佸畬鎴愰敭浣滀負(fù)涓鏉$邯褰曞姞鍏ュ埌榪欎釜瀹屾垚绔彛鐨勮澶囧垪琛ㄤ腑銆傚鏋滀綘鏈夊涓?strong>瀹屾垚绔彛錛屽氨浼?xì)鏈夊涓搴旂殑璁惧鍒楄〃銆傚鏋滆澶囧彞鏌勮鍏抽棴錛屽垯琛ㄤ腑鑷姩鍒犻櫎璇ョ邯褰曘?br />
4銆?strong>瀹屾垚绔彛綰跨▼鐨勫伐浣滃師鐞?/strong>
瀹屾垚绔彛鍙互甯姪鎴戜滑綆$悊綰跨▼姹狅紝浣嗘槸綰跨▼姹犱腑鐨勭嚎紼嬮渶瑕佹垜浠嬌鐢╛beginthreadex鏉ュ垱寤猴紝鍑粈涔堥氱煡瀹屾垚绔彛綆$悊鎴戜滑鐨勬柊綰跨▼鍛紵絳旀鍦ㄥ嚱鏁癎etQueuedCompletionStatus銆傝鍑芥暟鍘熷瀷錛?nbsp;
BOOL GetQueuedCompletionStatus(
IN HANDLE CompletionPort,
OUT LPDWORD lpNumberOfBytesTransferred,
OUT PULONG_PTR lpCompletionKey,
OUT LPOVERLAPPED *lpOverlapped,
IN DWORD dwMilliseconds
);
榪欎釜鍑芥暟璇曞浘浠庢寚瀹氱殑瀹屾垚绔彛鐨処/0瀹屾垚闃熷垪涓娊鍙栫邯褰曘傚彧鏈夊綋閲嶅彔I(yíng)/O鍔ㄤ綔瀹屾垚鐨勬椂鍊欙紝瀹屾垚闃熷垪涓墠鏈夌邯褰曘傚嚒鏄皟鐢ㄨ繖涓嚱鏁扮殑綰跨▼灝嗚鏀懼叆鍒?strong>瀹屾垚绔彛鐨勭瓑寰呯嚎紼嬮槦鍒椾腑錛屽洜姝?strong>瀹屾垚绔彛灝卞彲浠ュ湪鑷繁鐨勭嚎紼嬫睜涓府鍔╂垜浠淮鎶よ繖涓嚎紼嬨?strong>瀹屾垚绔彛鐨処/0瀹屾垚闃熷垪涓瓨鏀句簡(jiǎn)褰撻噸鍙營(yíng)/0瀹屾垚鐨勭粨鏋?--- 涓鏉$邯褰曪紝璇ョ邯褰曟嫢鏈夊洓涓瓧孌碉紝鍓嶄笁欏瑰氨瀵瑰簲GetQueuedCompletionStatus鍑芥暟鐨?銆?銆?鍙傛暟錛屾渶鍚庝竴涓瓧孌墊槸閿欒淇℃伅dwError銆傛垜浠篃鍙互閫氳繃璋冪敤PostQueudCompletionStatus妯℃嫙瀹屾垚浜?jiǎn)涓涓噸鍙營(yíng)/0鎿嶄綔銆?nbsp;
褰揑/0瀹屾垚闃熷垪涓嚭鐜頒簡(jiǎn)綰綍錛?strong>瀹屾垚绔彛灝嗕細(xì)媯(gè)鏌ョ瓑寰呯嚎紼嬮槦鍒楋紝璇ラ槦鍒椾腑鐨勭嚎紼嬮兘鏄氳繃璋冪敤GetQueuedCompletionStatus鍑芥暟浣胯嚜宸卞姞鍏ラ槦鍒楃殑銆傜瓑寰呯嚎紼嬮槦鍒楀緢綆鍗曪紝鍙槸淇濆瓨浜?jiǎn)杩欎簺绾拷E嬬殑ID銆?strong>瀹屾垚绔彛浼?xì)鎸夌収鍚帢q涘厛鍑虹殑鍘熷垯灝嗕竴涓嚎紼嬮槦鍒楃殑ID鏀懼叆鍒伴噴鏀劇嚎紼嬪垪琛ㄤ腑錛屽悓鏃惰綰跨▼灝嗕粠絳夊緟GetQueuedCompletionStatus鍑芥暟榪斿洖鐨勭潯鐪犵姸鎬佷腑鍙樹負(fù)鍙皟搴︾姸鎬佺瓑寰匔PU鐨勮皟搴︺傛墍浠ユ垜浠殑綰跨▼瑕佹兂鎴愪負(fù)瀹屾垚绔彛綆$悊鐨勭嚎紼嬶紝灝卞繀欏昏璋冪敤GetQueuedCompletionStatus鍑芥暟銆傚嚭浜庢ц兘鐨勪紭鍖栵紝瀹為檯涓?strong>瀹屾垚绔彛榪樼淮鎶や簡(jiǎn)涓涓殏鍋滅嚎紼嬪垪琛紝鍏蜂綋緇嗚妭鍙互鍙傝冦奧indows楂樼駭緙栫▼鎸囧崡銆嬶紝鎴戜滑鐜板湪鐭ラ亾鐨勭煡璇嗭紝宸茬粡瓚沖浜?jiǎn)銆?nbsp;瀹屾垚绔彛綰跨▼闂存暟鎹紶閫掔嚎紼嬮棿浼犻掓暟鎹渶甯哥敤鐨勫姙娉曟槸鍦╛beginthreadex鍑芥暟涓皢鍙傛暟浼犻掔粰綰跨▼鍑芥暟錛屾垨鑰呬嬌鐢ㄥ叏灞鍙橀噺銆備絾鏄?strong>瀹屾垚绔彛榪樻湁鑷繁鐨勪紶閫掓暟鎹殑鏂規(guī)硶錛岀瓟妗堝氨鍦ㄤ簬CompletionKey鍜孫VERLAPPED鍙傛暟銆?br />
CompletionKey琚繚瀛樺湪瀹屾垚绔彛鐨勮澶囪〃涓紝鏄拰璁懼鍙ユ焺涓涓瀵瑰簲鐨勶紝鎴戜滑鍙互灝嗕笌璁懼鍙ユ焺鐩稿叧鐨勬暟鎹繚瀛樺埌CompletionKey涓紝鎴栬呭皢CompletionKey琛ㄧず涓虹粨鏋勬寚閽堬紝榪欐牱灝卞彲浠ヤ紶閫掓洿鍔犱赴瀵岀殑鍐呭銆傝繖浜涘唴瀹瑰彧鑳藉湪涓寮濮嬪叧鑱?strong>瀹屾垚绔彛鍜岃澶囧彞鏌勭殑鏃跺欏仛錛屽洜姝や笉鑳藉湪浠ュ悗鍔ㄦ佹敼鍙樸?br />
OVERLAPPED鍙傛暟鏄湪姣忔璋冪敤ReadFile榪欐牱鐨勬敮鎸侀噸鍙營(yíng)/0鐨勫嚱鏁版椂浼犻掔粰瀹屾垚绔彛鐨勩傛垜浠彲浠ョ湅鍒幫紝濡傛灉鎴戜滑涓嶆槸瀵規(guī)枃浠惰澶囧仛鎿嶄綔錛岃緇撴瀯鐨勬垚鍛樺彉閲忓氨瀵規(guī)垜浠嚑涔庢鏃犱綔鐢ㄣ傛垜浠渶瑕侀檮鍔犱俊鎭紝鍙互鍒涘緩鑷繁鐨勭粨鏋勶紝鐒跺悗灝哋VERLAPPED緇撴瀯鍙橀噺浣滀負(fù)鎴戜滑緇撴瀯鍙橀噺鐨勭涓涓垚鍛橈紝鐒跺悗浼犻掔涓涓垚鍛樺彉閲忕殑鍦板潃緇橰eadFile鍑芥暟銆傚洜涓虹被鍨嬪尮閰嶏紝褰撶劧鍙互閫氳繃緙栬瘧銆傚綋GetQueuedCompletionStatus鍑芥暟榪斿洖鏃訛紝鎴戜滑鍙互鑾峰彇鍒扮涓涓垚鍛樺彉閲忕殑鍦板潃錛岀劧鍚庝竴涓畝鍗曠殑寮哄埗杞崲錛屾垜浠氨鍙互鎶婂畠褰撲綔瀹屾暣鐨勮嚜瀹氫箟緇撴瀯鐨勬寚閽堜嬌鐢紝榪欐牱灝卞彲浠ヤ紶閫掑緢澶氶檮鍔犵殑鏁版嵁浜?jiǎn)銆傚お濂戒簡(jiǎn)錛佸彧鏈変竴鐐硅娉ㄦ剰錛屽鏋滆法綰跨▼浼犻掞紝璇鋒敞鎰忓皢鏁版嵁鍒嗛厤鍒板爢涓婏紝騫朵笖鎺ユ敹绔簲璇ュ皢鏁版嵁鐢ㄥ畬鍚庨噴鏀俱傛垜浠氬父闇瑕佸皢ReadFile榪欐牱鐨勫紓姝ュ嚱鏁扮殑鎵闇瑕佺殑緙撳啿鍖烘斁鍒版垜浠嚜瀹氫箟鐨勭粨鏋勪腑錛岃繖鏍峰綋GetQueuedCompletionStatus琚繑鍥炴椂錛屾垜浠殑鑷畾涔夌粨鏋勭殑緙撳啿鍖哄彉閲忎腑灝卞瓨鏀句簡(jiǎn)I/0鎿嶄綔鐨勬暟鎹侰ompletionKey鍜孫VERLAPPED鍙傛暟錛岄兘鍙互閫氳繃GetQueuedCompletionStatus鍑芥暟鑾峰緱銆?br />
綰跨▼鐨勫畨鍏ㄩ鍑?br />
寰堝綰跨▼涓轟簡(jiǎn)涓嶆涓嬈$殑鎵ц寮傛鏁版嵁澶勭悊錛岄渶瑕佷嬌鐢ㄥ涓嬭鍙?br />
while (true)
{
......
GetQueuedCompletionStatus(...);
......
}
閭d箞濡備綍閫鍑哄憿錛岀瓟妗堝氨鍦ㄤ簬涓婇潰鏇炬彁鍒扮殑PostQueudCompletionStatus鍑芥暟錛屾垜浠彲浠ョ敤瀹冨彂閫佷竴涓嚜瀹氫箟鐨勫寘鍚簡(jiǎn)OVERLAPPED鎴愬憳鍙橀噺鐨勭粨鏋勫湴鍧錛岄噷闈㈠寘鍚竴涓姸鎬佸彉閲忥紝褰撶姸鎬佸彉閲忎負(fù)閫鍑烘爣蹇楁椂錛岀嚎紼嬪氨鎵ц娓呴櫎鍔ㄤ綔鐒跺悗閫鍑恒?br />
5銆乄indows瀹屾垚绔彛鐨勫疄渚嬩唬鐮侊細(xì)
DWORD WINAPI WorkerThread(LPVOID lpParam)
{
ULONG_PTR *PerHandleKey;
OVERLAPPED *Overlap;
OVERLAPPEDPLUS *OverlapPlus,
*newolp;
DWORD dwBytesXfered;
while (1)
{
ret = GetQueuedCompletionStatus(
hIocp,
&dwBytesXfered,
(PULONG_PTR)&PerHandleKey,
&Overlap,
INFINITE);
if (ret == 0)
{
// Operation failed
continue;
}
OverlapPlus = CONTAINING_RECORD(Overlap, OVERLAPPEDPLUS, ol);
switch (OverlapPlus->OpCode)
{
case OP_ACCEPT:
// Client socket is contained in OverlapPlus.sclient
// Add client to completion port
CreateIoCompletionPort(
(HANDLE)OverlapPlus->sclient,
hIocp,
(ULONG_PTR)0,
0);
// Need a new OVERLAPPEDPLUS structure
// for the newly accepted socket. Perhaps
// keep a look aside list of free structures.
newolp = AllocateOverlappedPlus();
if (!newolp)
{
// Error
}
newolp->s = OverlapPlus->sclient;
newolp->OpCode = OP_READ;
// This function divpares the data to be sent
PrepareSendBuffer(&newolp->wbuf);
ret = WSASend(
newolp->s,
&newolp->wbuf,
1,
&newolp->dwBytes,
0,
&newolp.ol,
NULL);
if (ret == SOCKET_ERROR)
{
if (WSAGetLastError() != WSA_IO_PENDING)
{
// Error
}
}
// Put structure in look aside list for later use
FreeOverlappedPlus(OverlapPlus);
// Signal accept thread to issue another AcceptEx
SetEvent(hAcceptThread);
break;
case OP_READ:
// Process the data read
// Repost the read if necessary, reusing the same
// receive buffer as before
memset(&OverlapPlus->ol, 0, sizeof(OVERLAPPED));
ret = WSARecv(
OverlapPlus->s,
&OverlapPlus->wbuf,
1,
&OverlapPlus->dwBytes,
&OverlapPlus->dwFlags,
&OverlapPlus->ol,
NULL);
if (ret == SOCKET_ERROR)
{
if (WSAGetLastError() != WSA_IO_PENDING)
{
// Error
}
}
break;
case OP_WRITE:
// Process the data sent, etc.
break;
} // switch
} // while
} // WorkerThread
鏌ョ湅浠ヤ笂浠g爜錛屾敞鎰忓鏋淥verlapped鎿嶄綔绔嬪埢澶辮觸錛堟瘮濡傦紝榪斿洖SOCKET_ERROR鎴栧叾浠栭潪WSA_IO_PENDING鐨勯敊璇級(jí)錛屽垯娌℃湁浠諱綍瀹屾垚閫氱煡鏃墮棿浼?xì)琚攽謭?strong>瀹屾垚绔彛闃熷垪閲屻傚弽涔嬶紝鍒欎竴瀹氭湁鐩稿簲鐨勯氱煡鏃墮棿琚斁鍒?strong>瀹屾垚绔彛闃熷垪銆傛洿瀹屽杽鐨勫叧浜嶹insock鐨?strong>瀹屾垚绔彛鏈哄埗錛屽彲浠ュ弬鑰僊SDN鐨凪icrosoft PlatFormSDK錛岄偅閲屾湁瀹屾垚绔彛鐨勪緥瀛愩傝闂?a >http://msdn.microsoft.com/library/techart/msdn_servrapp.htm鍙互鑾峰緱鏇村淇℃伅銆?/p>
Linux鐨?strong>EPoll妯″瀷
Linux 2.6鍐呮牳涓彁楂樼綉緇淚/O鎬ц兘鐨勬柊鏂規(guī)硶-epoll I/O澶氳礬澶嶇敤鎶鏈湪姣旇緝澶氱殑TCP緗戠粶鏈嶅姟鍣ㄤ腑鏈変嬌鐢紝鍗蟲瘮杈冨鐨勭敤鍒皊elect鍑芥暟銆?br />
1銆佷負(fù)浠涔坰elect钀藉悗
棣栧厛錛屽湪Linux鍐呮牳涓紝select鎵鐢ㄥ埌鐨凢D_SET鏄湁闄愮殑錛屽嵆鍐呮牳涓湁涓弬鏁癬_FD_SETSIZE瀹氫箟浜?jiǎn)姣忎釜FD_SET鐨勫彞鏌勪釜鏁幫紝鍦ㄦ垜鐢ㄧ殑2.6.15-25-386鍐呮牳涓紝璇ュ兼槸1024錛屾悳绱㈠唴鏍告簮浠g爜寰楀埌錛?br />
include/linux/posix_types.h:#define __FD_SETSIZE 1024
涔熷氨鏄錛屽鏋滄兂瑕佸悓鏃舵嫻?025涓彞鏌勭殑鍙鐘舵佹槸涓嶅彲鑳界敤select瀹炵幇鐨勩傛垨鑰呭悓鏃舵嫻?025涓彞鏌勭殑鍙啓鐘舵佷篃鏄笉鍙兘鐨勩傚叾嬈★紝鍐呮牳涓疄鐜皊elect鏄敤杞鏂規(guī)硶錛屽嵆姣忔媯(gè)嫻嬮兘浼?xì)閬嶅巻鎵鏈塅D_SET涓殑鍙ユ焺錛屾樉鐒?dòng)灱宻elect鍑芥暟鎵ц鏃墮棿涓嶧D_SET涓殑鍙ユ焺涓暟鏈変竴涓瘮渚嬪叧緋伙紝鍗硈elect瑕佹嫻嬬殑鍙ユ焺鏁拌秺澶氬氨浼?xì)瓒婅匆?guī)椂銆傚綋鐒?dòng)灱屽湪鍓嶆枃涓垜迤堟病鏈夋彁鍙?qiáng)poll鏂規(guī)硶錛屼簨瀹炰笂鐢╯elect鐨勬湅鍙嬩竴瀹氫篃璇曡繃poll錛屾垜涓漢瑙夊緱select鍜宲oll澶у悓灝忓紓錛屼釜浜哄亸濂戒簬鐢╯elect鑰屽凡銆?/p>
2銆佸唴鏍鎬腑鎻愰珮I(yè)/O鎬ц兘鐨勬柊鏂規(guī)硶epoll
epoll鏄粈涔堬紵鎸夌収man鎵嬪唽鐨勮娉曪細(xì)鏄負(fù)澶勭悊澶ф壒閲忓彞鏌勮屼綔浜?jiǎn)鏀箻q涚殑poll銆傝浣跨敤epoll鍙渶瑕佽繖涓変釜緋葷粺璋冪敤錛?strong>epoll_create(2)錛?nbsp;epoll_ctl(2)錛?nbsp;epoll_wait(2)銆?br />
褰撶劧錛岃繖涓嶆槸2.6鍐呮牳鎵嶆湁鐨勶紝瀹冩槸鍦?.5.44鍐呮牳涓寮曡繘鐨?epoll(4) is a new API introduced in Linux kernel 2.5.44)
Linux2.6鍐呮牳epoll浠嬬粛
鍏堜粙緇?鏈功銆奣he Linux Networking Architecture--Design and Implementation of Network Protocols in the Linux Kernel銆嬶紝浠?.4鍐呮牳璁茶ВLinux TCP/IP瀹炵幇錛岀浉褰撲笉閿?浣滀負(fù)涓涓幇瀹炰笘鐣屼腑鐨勫疄鐜幫紝寰堝鏃跺欎綘蹇呴』浣滃緢澶氭潈琛★紝榪欐椂鍊欏弬鑰冧竴涓箙緇忚冮獙鐨勭郴緇熸洿鏈夊疄闄呮剰涔夈備婦涓緥瀛?linux鍐呮牳涓璼k_buff緇撴瀯涓轟簡(jiǎn)榪芥眰閫熷害鍜屽畨鍏紝鐗虹壊浜?jiǎn)閮ㄥ垎鍐呭瓨锛屾墍浠ュ湪鍙戦乀CP鍖呯殑鏃跺欙紝鏃犺搴旂敤灞傛暟鎹澶?sk_buff鏈灝忎篃鏈?72鐨勫瓧鑺?鍏跺疄瀵逛簬socket搴旂敤灞傜▼搴忔潵璇達(dá)紝鍙﹀涓鏈功銆奤NIX Network Programming Volume 1銆嬫剰涔夋洿澶т竴鐐?2003騫寸殑鏃跺欙紝榪欐湰涔﹀嚭浜?jiǎn)鏈鏂扮殑絎?鐗堟湰錛屼笉榪囦富瑕佽繕鏄慨璁㈢2鐗堟湰銆傚叾涓6绔犮奍/O Multiplexing銆嬫槸鏈閲嶈鐨勩係tevens緇欏嚭浜?jiǎn)缃懢l淚O鐨勫熀鏈ā鍨嬨傚湪榪欓噷鏈閲嶈鐨勮帿榪囦簬select妯″瀷鍜孉synchronous I/O妯″瀷.浠庣悊璁轟笂璇達(dá)紝AIO浼間箮鏄渶楂樻晥鐨勶紝浣犵殑IO鎿嶄綔鍙互绔嬪嵆榪斿洖錛岀劧鍚庣瓑寰卭s鍛婅瘔浣營(yíng)O鎿嶄綔瀹屾垚銆備絾鏄竴鐩翠互鏉ワ紝濡備綍瀹炵幇灝辨病鏈変竴涓畬緹庣殑鏂規(guī)銆傛渶钁楀悕鐨剋indows瀹屾垚绔彛瀹炵幇鐨凙IO,瀹為檯涓婁篃鏄唴閮ㄧ敤綰跨▼姹犲疄鐜扮殑緗簡(jiǎn)錛屾渶鍚庣殑緇撴灉鏄疘O鏈変釜綰跨▼姹狅紝浣犲簲鐢ㄤ篃闇瑕佷竴涓嚎紼嬫睜...... 寰堝鏂囨。鍏跺疄宸茬粡鎸囧嚭浜?jiǎn)杩欏甫鏉ョ殑绾拷E媍ontext-switch甯︽潵鐨勪唬浠楓傚湪linux 騫沖彴涓婏紝鍏充簬緗戠粶AIO涓鐩存槸鏀瑰姩鏈澶氱殑鍦版柟錛?.4鐨勫勾浠e氨鏈夊緢澶欰IO鍐呮牳patch,鏈钁楀悕鐨勫簲璇ョ畻鏄疭GI閭d釜銆備絾鏄竴鐩村埌2.6鍐呮牳鍙戝竷錛岀綉緇滄ā鍧楃殑AIO涓鐩存病鏈夎繘鍏ョǔ瀹氬唴鏍哥増鏈?澶ч儴鍒嗛兘鏄嬌鐢ㄧ敤鎴風(fēng)嚎紼嬫ā鎷熸柟娉曪紝鍦ㄤ嬌鐢ㄤ簡(jiǎn)NPTL鐨刲inux涓婇潰鍏跺疄鍜寃indows鐨?strong>瀹屾垚绔彛鍩烘湰涓婂樊涓嶅浜?銆?.6鍐呮牳鎵鏀寔鐨凙IO鐗規(guī)寚紓佺洏鐨凙IO---鏀寔io_submit(),io_getevents()浠ュ強(qiáng)瀵笵irect IO鐨勬敮鎸?灝辨槸緇曡繃VFS緋葷粺buffer鐩存帴鍐欑‖鐩橈紝瀵逛簬嫻佹湇鍔″櫒鍦ㄥ唴瀛樺鉤紼蟲т笂鏈夌浉褰撳府鍔?銆?br />
鎵浠ワ紝鍓╀笅鐨剆elect妯″瀷鍩烘湰涓婂氨鏄垜浠湪linux涓婇潰鐨勫敮涓閫夋嫨錛屽叾瀹烇紝濡傛灉鍔犱笂no-block socket鐨勯厤緗紝鍙互瀹屾垚涓涓?浼?AIO鐨勫疄鐜幫紝鍙笉榪囨帹鍔ㄥ姏鍦ㄤ簬浣犺屼笉鏄痮s鑰屽凡銆備笉榪囦紶緇熺殑select/poll鍑芥暟鏈夌潃涓浜涙棤娉曞繊鍙楃殑緙虹偣錛屾墍浠ユ敼榪涗竴鐩存槸2.4-2.5寮鍙戠増鏈唴鏍哥殑浠誨姟錛屽寘鎷?dev/poll錛宺ealtime signal絳夌瓑銆傛渶緇堬紝Davide Libenzi寮鍙戠殑epoll榪涘叆2.6鍐呮牳鎴愪負(fù)姝e紡鐨勮В鍐蟲柟妗?br />
3銆?strong>epoll鐨勪紭鐐?/strong>
<1>鏀寔涓涓繘紼嬫墦寮澶ф暟鐩殑socket鎻忚堪絎?FD)
select 鏈涓嶈兘蹇嶅彈鐨勬槸涓涓繘紼嬫墍鎵撳紑鐨凢D鏄湁涓瀹氶檺鍒剁殑錛岀敱FD_SETSIZE璁劇疆錛岄粯璁ゅ兼槸2048銆傚浜庨偅浜涢渶瑕佹敮鎸佺殑涓婁竾榪炴帴鏁扮洰鐨処M鏈嶅姟鍣ㄦ潵璇存樉鐒跺お灝戜簡(jiǎn)銆傝繖鏃跺欎綘涓鏄彲浠ラ夋嫨淇敼榪欎釜瀹忕劧鍚庨噸鏂扮紪璇戝唴鏍革紝涓嶈繃璧勬枡涔熷悓鏃舵寚鍑?guó)櫩欐牱浼?xì)甯︽潵緗戠粶鏁堢巼鐨勪笅闄嶏紝浜屾槸鍙互閫夋嫨澶氳繘紼嬬殑瑙e喅鏂規(guī)(浼犵粺鐨凙pache鏂規(guī))錛屼笉榪囪櫧鐒秎inux涓婇潰鍒涘緩榪涚▼鐨勪唬浠鋒瘮杈冨皬錛屼絾浠嶆棫鏄笉鍙拷瑙嗙殑錛屽姞涓婅繘紼嬮棿鏁版嵁鍚屾榪滄瘮涓嶄笂綰跨▼闂村悓姝ョ殑楂樻晥錛屾墍浠ヤ篃涓嶆槸涓縐嶅畬緹庣殑鏂規(guī)銆備笉榪?nbsp;epoll鍒欐病鏈夎繖涓檺鍒訛紝瀹冩墍鏀寔鐨凢D涓婇檺鏄渶澶у彲浠ユ墦寮鏂囦歡鐨勬暟鐩紝榪欎釜鏁板瓧涓鑸繙澶т簬2048,涓句釜渚嬪瓙,鍦?GB鍐呭瓨鐨勬満鍣ㄤ笂澶х害鏄?0涓囧乏鍙籌紝鍏蜂綋鏁扮洰鍙互cat /proc/sys/fs/file-max瀵熺湅,涓鑸潵璇磋繖涓暟鐩拰緋葷粺鍐呭瓨鍏崇郴寰堝ぇ銆?br />
<2>IO鏁堢巼涓嶉殢FD鏁扮洰澧炲姞鑰岀嚎鎬т笅闄?br />
浼犵粺鐨剆elect/poll鍙︿竴涓嚧鍛藉急鐐瑰氨鏄綋浣犳嫢鏈変竴涓緢澶х殑socket闆嗗悎錛屼笉榪囩敱浜庣綉緇滃歡鏃訛紝浠諱竴鏃墮棿鍙湁閮ㄥ垎鐨剆ocket鏄?媧昏穬"鐨勶紝浣嗘槸select/poll姣忔璋冪敤閮戒細(xì)綰挎ф壂鎻忓叏閮ㄧ殑闆嗗悎錛屽鑷存晥鐜囧憟鐜扮嚎鎬т笅闄嶃備絾鏄?strong>epoll涓嶅瓨鍦ㄨ繖涓棶棰橈紝瀹冨彧浼?xì)瀵?媧昏穬"鐨剆ocket榪涜鎿嶄綔---榪欐槸鍥犱負(fù)鍦ㄥ唴鏍稿疄鐜頒腑epoll鏄牴鎹瘡涓猣d涓婇潰鐨刢allback鍑芥暟瀹炵幇鐨勩傞偅涔堬紝鍙湁"媧昏穬"鐨剆ocket鎵嶄細(xì)涓誨姩鐨勫幓璋冪敤 callback鍑芥暟錛屽叾浠杋dle鐘舵乻ocket鍒欎笉浼?xì)锛屽湪杩欑偣涓婂Q?strong>epoll瀹炵幇浜?jiǎn)涓涓?浼?AIO錛屽洜涓鴻繖鏃跺欐帹鍔ㄥ姏鍦╫s鍐呮牳銆傚湪涓浜?benchmark涓紝濡傛灉鎵鏈夌殑socket鍩烘湰涓婇兘鏄椿璺冪殑---姣斿涓涓珮閫烲AN鐜錛?strong>epoll騫朵笉姣攕elect/poll鏈変粈涔堟晥鐜囷紝鐩稿弽錛屽鏋滆繃澶氫嬌鐢?strong>epoll_ctl,鏁堢巼鐩告瘮榪樻湁紼嶅井鐨勪笅闄嶃備絾鏄竴鏃︿嬌鐢╥dle connections妯℃嫙WAN鐜,epoll鐨勬晥鐜囧氨榪滃湪select/poll涔嬩笂浜?jiǎn)銆?br />
<3>浣跨敤mmap鍔犻熷唴鏍鎬笌鐢ㄦ埛絀洪棿鐨勬秷鎭紶閫掋?br />
榪欑偣瀹為檯涓婃秹鍙?qiáng)鍒?strong>epoll鐨勫叿浣撳疄鐜頒簡(jiǎn)銆傛棤璁烘槸select,poll榪樻槸epoll閮介渶瑕佸唴鏍告妸FD娑堟伅閫氱煡緇欑敤鎴風(fēng)┖闂達(dá)紝濡備綍閬垮厤涓嶅繀瑕佺殑鍐呭瓨鎷瘋礉灝卞緢閲嶈錛屽湪榪欑偣涓婏紝epoll鏄氳繃鍐呮牳浜庣敤鎴風(fēng)┖闂磎map鍚屼竴鍧楀唴瀛樺疄鐜扮殑銆傝屽鏋滀綘鎯蟲垜涓鏍蜂粠2.5鍐呮牳灝卞叧娉?strong>epoll鐨勮瘽錛屼竴瀹氫笉浼?xì)蹇樿鎵嬪?mmap榪欎竴姝ョ殑銆?br />
<4>鍐呮牳寰皟
榪欎竴鐐瑰叾瀹炰笉綆?strong>epoll鐨勪紭鐐逛簡(jiǎn)錛岃屾槸鏁翠釜linux騫沖彴鐨勪紭鐐廣備篃璁鎬綘鍙互鎬鐤憀inux騫沖彴錛屼絾鏄綘鏃犳硶鍥為伩linux騫沖彴璧嬩簣浣犲井璋冨唴鏍哥殑鑳藉姏銆傛瘮濡傦紝鍐呮牳TCP/IP鍗忚鏍堜嬌鐢ㄥ唴瀛樻睜綆$悊sk_buff緇撴瀯錛岄偅涔堝彲浠ュ湪榪愯鏃舵湡鍔ㄦ佽皟鏁磋繖涓唴瀛榩ool(skb_head_pool)鐨勫ぇ灝?-- 閫氳繃echo XXXX>/proc/sys/net/core/hot_list_length瀹屾垚銆傚啀姣斿listen鍑芥暟鐨勭2涓弬鏁?TCP瀹屾垚3嬈℃彙鎵嬬殑鏁版嵁鍖呴槦鍒楅暱搴?錛屼篃鍙互鏍規(guī)嵁浣犲鉤鍙板唴瀛樺ぇ灝忓姩鎬佽皟鏁淬傛洿鐢氳嚦鍦ㄤ竴涓暟鎹寘闈㈡暟鐩法澶т絾鍚屾椂姣忎釜鏁版嵁鍖呮湰韜ぇ灝忓嵈寰堝皬鐨勭壒孌婄郴緇熶笂灝濊瘯鏈鏂扮殑NAPI緗戝崱椹卞姩鏋舵瀯銆?br />
4銆?strong>epoll鐨勫伐浣滄ā寮?br />
浠や漢楂樺叴鐨勬槸錛?.6鍐呮牳鐨?strong>epoll姣斿叾2.5寮鍙戠増鏈殑/dev/epoll綆媧佷簡(jiǎn)璁稿錛屾墍浠ワ紝澶ч儴鍒嗘儏鍐典笅錛屽己澶х殑涓滆タ寰寰鏄畝鍗曠殑銆傚敮涓鏈夌偣楹葷儲(chǔ)鏄?strong>epoll鏈?縐嶅伐浣滄柟寮?LT鍜孍T銆?br />
LT(level triggered)鏄己鐪佺殑宸ヤ綔鏂瑰紡錛屽茍涓斿悓鏃舵敮鎸乥lock鍜宯o-block socket.鍦ㄨ繖縐嶅仛娉曚腑錛屽唴鏍稿憡璇変綘涓涓枃浠舵弿榪扮鏄惁灝辯華浜?jiǎn)锛岀劧鍚庝綘鍙互瀵箻q欎釜灝辯華鐨刦d榪涜IO鎿嶄綔銆傚鏋滀綘涓嶄綔浠諱綍鎿嶄綔錛屽唴鏍歌繕鏄細(xì)緇х畫閫氱煡浣犵殑錛屾墍浠ワ紝榪欑妯″紡緙栫▼鍑洪敊璇彲鑳芥ц灝忎竴鐐廣備紶緇熺殑select/poll閮芥槸榪欑妯″瀷鐨勪唬琛紟
ET (edge-triggered)鏄珮閫熷伐浣滄柟寮忥紝鍙敮鎸乶o-block socket銆傚湪榪欑妯″紡涓嬶紝褰撴弿榪扮浠庢湭灝辯華鍙樹負(fù)灝辯華鏃訛紝鍐呮牳閫氳繃epoll鍛婅瘔浣犮傜劧鍚庡畠浼?xì)鍋囪浣犵煡閬撴枃錃g鎻忚堪絎﹀凡緇忓氨緇紝騫朵笖涓嶄細(xì)鍐嶄負(fù)閭d釜鏂囦歡鎻忚堪絎﹀彂閫佹洿澶氱殑灝辯華閫氱煡錛岀洿鍒頒綘鍋氫簡(jiǎn)鏌愪簺鎿嶄綔瀵艱嚧閭d釜鏂囦歡鎻忚堪絎︿笉鍐嶄負(fù)灝辯華鐘舵佷簡(jiǎn)(姣斿錛屼綘鍦ㄥ彂閫侊紝鎺ユ敹鎴栬呮帴鏀惰姹傦紝鎴栬呭彂閫佹帴鏀剁殑鏁版嵁灝戜簬涓瀹氶噺鏃跺鑷翠簡(jiǎn)涓涓狤WOULDBLOCK 閿欒錛夈備絾鏄娉ㄦ剰錛屽鏋滀竴鐩翠笉瀵硅繖涓猣d浣淚O鎿嶄綔(浠庤屽鑷村畠鍐嶆鍙樻垚鏈氨緇?錛屽唴鏍鎬笉浼?xì)鍙戦佹洿澶氱殑閫氱煡(only once),涓嶈繃鍦═CP鍗忚涓紝ET妯″紡鐨勫姞閫熸晥鐢ㄤ粛闇瑕佹洿澶氱殑benchmark紜銆?br />
epoll鍙湁epoll_create,epoll_ctl,epoll_wait 3涓郴緇熻皟鐢紝鍏蜂綋鐢ㄦ硶璇峰弬鑰?a >http://www.xmailserver.org/linux-patches/nio-improve.html 錛屽湪http://www.kegel.com/rn/涔熸湁涓涓畬鏁寸殑渚嬪瓙錛屽ぇ瀹朵竴鐪嬪氨鐭ラ亾濡備綍浣跨敤浜?br />
Leader/follower妯″紡綰跨▼pool瀹炵幇錛屼互鍙?qiáng)鍜?strong>epoll鐨勯厤鍚堛?br />
5銆?nbsp;epoll鐨勪嬌鐢ㄦ柟娉?/strong>
棣栧厛閫氳繃create_epoll(int maxfds)鏉ュ垱寤轟竴涓?strong>epoll鐨勫彞鏌勶紝鍏朵腑maxfds涓轟綘epoll鎵鏀寔鐨勬渶澶у彞鏌勬暟銆傝繖涓嚱鏁頒細(xì)榪斿洖涓涓柊鐨?strong>epoll鍙ユ焺錛屼箣鍚庣殑鎵鏈夋搷浣滃皢閫氳繃榪欎釜鍙ユ焺鏉ヨ繘琛屾搷浣溿傚湪鐢ㄥ畬涔嬪悗錛岃寰楃敤close()鏉ュ叧闂繖涓垱寤哄嚭鏉ョ殑epoll鍙ユ焺銆?涔嬪悗鍦ㄤ綘鐨勭綉緇滀富寰幆閲岄潰錛屾瘡涓甯х殑璋冪敤epoll_wait(int epfd, epoll_event events, int max events, int timeout)鏉ユ煡璇㈡墍鏈夌殑緗戠粶鎺ュ彛錛岀湅鍝竴涓彲浠ヨ錛屽摢涓涓彲浠ュ啓浜?jiǎn)銆傚熀鏈殑璇硶涓猴細(xì)
nfds = epoll_wait(kdpfd, events, maxevents, -1);
鍏朵腑kdpfd涓虹敤epoll_create鍒涘緩涔嬪悗鐨勫彞鏌勶紝events鏄竴涓?strong>epoll_event*鐨勬寚閽堬紝褰?strong>epoll_wait榪欎釜鍑芥暟鎿嶄綔鎴愬姛涔嬪悗錛?strong>epoll_events閲岄潰灝嗗偍瀛樻墍鏈夌殑璇誨啓浜嬩歡銆俶ax_events鏄綋鍓嶉渶瑕佺洃鍚殑鎵鏈塻ocket鍙ユ焺鏁般傛渶鍚庝竴涓猼imeout鏄?strong>epoll_wait鐨勮秴鏃訛紝涓?鐨勬椂鍊欒〃紺洪┈涓婅繑鍥烇紝涓?1鐨勬椂鍊欒〃紺轟竴鐩寸瓑涓嬪幓錛岀洿鍒版湁浜嬩歡鑼冨洿錛屼負(fù)浠繪剰姝f暣鏁扮殑鏃跺欒〃紺虹瓑榪欎箞闀跨殑鏃墮棿錛屽鏋滀竴鐩存病鏈変簨浠訛紝鍒欒寖鍥淬備竴鑸鏋滅綉緇滀富寰幆鏄崟鐙殑綰跨▼鐨勮瘽錛屽彲浠ョ敤-1鏉ョ瓑錛岃繖鏍峰彲浠ヤ繚璇佷竴浜涙晥鐜囷紝濡傛灉鏄拰涓婚昏緫鍦ㄥ悓涓涓嚎紼嬬殑璇濓紝鍒欏彲浠ョ敤0鏉ヤ繚璇佷富寰幆鐨勬晥鐜囥?/p>
epoll_wait鑼冨洿涔嬪悗搴旇鏄竴涓驚鐜紝閬嶅埄鎵鏈夌殑浜嬩歡錛?nbsp;
for(n = 0; n < nfds; ++n) {
if(events[n].data.fd == listener) { //濡傛灉鏄富socket鐨勪簨浠剁殑璇濓紝鍒欒〃紺烘湁鏂拌繛鎺ヨ繘鍏ヤ簡(jiǎn)錛岃繘琛屾柊榪炴帴鐨勫鐞嗐?nbsp;
client = accept(listener, (struct sockaddr *) &local,
&addrlen);
if(client < 0){
perror("accept");
continue;
}
setnonblocking(client); // 灝嗘柊榪炴帴緗簬闈為樆濉炴ā寮?nbsp;
ev.events = EPOLLIN | EPOLLET; // 騫朵笖灝嗘柊榪炴帴涔熷姞鍏?strong>EPOLL鐨勭洃鍚槦鍒椼?nbsp;
娉ㄦ剰錛岃繖閲岀殑鍙傛暟EPOLLIN | EPOLLET騫舵病鏈夎緗鍐檚ocket鐨勭洃鍚紝濡傛灉鏈夊啓鎿嶄綔鐨勮瘽錛岃繖涓椂鍊?strong>epoll鏄笉浼?xì)杩斿洖浜嬩欢鐨勫Q屽鏋滆瀵瑰啓鎿嶄綔涔熺洃鍚殑璇濓紝搴旇鏄疎POLLIN | EPOLLOUT | EPOLLET
ev.data.fd = client;
if (epoll_ctl(kdpfd, EPOLL_CTL_ADD, client, &ev) < 0) {
// 璁劇疆濂絜vent涔嬪悗錛屽皢榪欎釜鏂扮殑event閫氳繃epoll_ctl鍔犲叆鍒?strong>epoll鐨勭洃鍚槦鍒楅噷闈紝榪欓噷鐢?strong>EPOLL_CTL_ADD鏉ュ姞涓涓柊鐨?strong>epoll浜嬩歡錛岄氳繃EPOLL_CTL_DEL鏉ュ噺灝戜竴涓?strong>epoll浜嬩歡錛岄氳繃EPOLL_CTL_MOD鏉ユ敼鍙樹竴涓簨浠剁殑鐩戝惉鏂瑰紡銆?nbsp;
fprintf(stderr, "epoll set insertion error: fd=%d0,
client);
return -1;
}
}
else // 濡傛灉涓嶆槸涓籹ocket鐨勪簨浠剁殑璇濓紝鍒欎唬琛ㄦ槸涓涓敤鎴穝ocket鐨勪簨浠訛紝鍒欐潵澶勭悊榪欎釜鐢ㄦ埛socket鐨勪簨鎯咃紝姣斿璇磖ead(fd,xxx)涔嬬被鐨勶紝鎴栬呬竴浜涘叾浠栫殑澶勭悊銆?nbsp;
do_use_fd(events[n].data.fd);
}
瀵癸紝epoll鐨勬搷浣滃氨榪欎箞綆鍗曪紝鎬誨叡涓嶈繃4涓狝PI錛?strong>epoll_create, epoll_ctl, epoll_wait鍜宑lose銆?nbsp;
濡傛灉鎮(zhèn)ㄥepoll鐨勬晥鐜囪繕涓嶅お浜?jiǎn)瑙eQ岃鍙傝冩垜涔嬪墠鍏充簬緗戠粶娓告垙鐨勭綉緇滅紪紼嬬瓑鐩稿叧鐨勬枃绔犮?/p>
浠ュ墠鍏徃鐨勬湇鍔″櫒閮芥槸浣跨敤HTTP榪炴帴錛屼絾鏄繖鏍風(fēng)殑璇濓紝鍦ㄦ墜鏈虹洰鍓嶇殑緗戠粶鎯呭喌涓嬩笉浣嗘樉寰楅熷害杈冩參錛岃屼笖涓嶇ǔ瀹氥傚洜姝ゅぇ瀹朵竴鑷村悓鎰忕敤SOCKET鏉ヨ繘琛岃繛鎺ャ傝櫧鐒朵嬌鐢⊿OCKET涔嬪悗錛屽浜庣敤鎴風(fēng)殑璐圭敤鍙兘浼?xì)澧炲?鐢變簬鏄敤浜?jiǎn)CMNET鑰岄潪CMWAP)錛屼絾鏄紝縐夌潃鐢ㄦ埛浣撻獙鑷充笂鐨勫師鍒欙紝鐩鎬俊澶у榪樻槸鑳藉鎺ュ彈鐨?甯屾湜閭d簺鐜╁鏈堟湯鏀跺埌甯愬崟涓嶅悗鑳藉淇濇寔鍏嬪埗...)銆?br />
榪欐鐨勬湇鍔″櫒璁捐涓紝鏈閲嶈鐨勪竴涓獊鐮達(dá)紝鏄嬌鐢ㄤ簡(jiǎn)EPOLL妯″瀷錛岃櫧鐒跺涔嬩篃鏄竴鐭ュ崐瑙o紝浣嗘槸鏃㈢劧鍦ㄥ悇澶C緗戞父涓凡緇忕粡榪囦簡(jiǎn)濡傛涓ラ叿鐨勮冮獙錛岀浉淇′粬涓嶄細(xì)璁╂垜浠け鏈涳紝浣跨敤鍚庣殑緇撴灉錛岀‘瀹炰篃鏄〃鐜扮浉褰撲笉閿欍傚湪榪欓噷錛屾垜榪樻槸涓昏澶ц嚧浠嬬粛涓涓嬭繖涓ā鍨嬬殑緇撴瀯銆?br />
6銆丩inux涓?strong>EPOll緙栫▼瀹炰緥
EPOLL妯″瀷浼間箮鍙湁涓縐嶆牸寮忥紝鎵浠ュぇ瀹跺彧瑕佸弬鑰冩垜涓嬮潰鐨勪唬鐮侊紝灝辮兘澶熷EPOLL鏈夋墍浜?jiǎn)瑙d簡(jiǎn)锛屼唬鐮佺殑瑙i噴閮藉凡缁忓湪娉ㄩ噴涓Q?/p>
while (TRUE)
{
int nfds = epoll_wait (m_epoll_fd, m_events, MAX_EVENTS, EPOLL_TIME_OUT);//絳夊緟EPOLL鏃墮棿鐨勫彂鐢燂紝鐩稿綋浜庣洃鍚紝鑷充簬鐩稿叧鐨勭鍙o紝闇瑕佸湪鍒濆鍖?strong>EPOLL鐨勬椂鍊欑粦瀹氥?br />
if (nfds <= 0)
continue;
m_bOnTimeChecking = FALSE;
G_CurTime = time(NULL);
for (int i=0; i
{
try
{
if (m_events[i].data.fd == m_listen_http_fd)//濡傛灉鏂扮洃嫻嬪埌涓涓狧TTP鐢ㄦ埛榪炴帴鍒扮粦瀹氱殑HTTP绔彛錛屽緩绔嬫柊鐨勮繛鎺ャ傜敱浜庢垜浠柊閲囩敤浜?jiǎn)SOCKET榪炴帴錛屾墍浠ュ熀鏈病鐢ㄣ?br />
{
OnAcceptHttpEpoll ();
}
else if (m_events[i].data.fd == m_listen_sock_fd)//濡傛灉鏂扮洃嫻嬪埌涓涓猄OCKET鐢ㄦ埛榪炴帴鍒頒簡(jiǎn)緇戝畾鐨凷OCKET绔彛錛屽緩绔嬫柊鐨勮繛鎺ャ?br />
{
OnAcceptSockEpoll ();
}
else if (m_events[i].events & EPOLLIN)//濡傛灉鏄凡緇忚繛鎺ョ殑鐢ㄦ埛錛屽茍涓旀敹鍒版暟鎹紝閭d箞榪涜璇誨叆銆?br />
{
OnReadEpoll (i);
}
OnWriteEpoll (i);//鏌ョ湅褰撳墠鐨勬椿鍔ㄨ繛鎺ユ槸鍚︽湁闇瑕佸啓鍑虹殑鏁版嵁銆?br />
}
catch (int)
{
PRINTF ("CATCH鎹曡幏閿欒\n");
continue;
}
}
m_bOnTimeChecking = TRUE;
OnTimer ();//榪涜涓浜涘畾鏃剁殑鎿嶄綔錛屼富瑕佸氨鏄垹闄や竴浜涚煭綰跨敤鎴風(fēng)瓑銆?br />
}
鍏跺疄EPOLL鐨勭簿鍗庯紝涔熷氨鏄笂榪扮殑鍑犳鐭煭鐨勪唬鐮侊紝鐪嬫潵鏃朵唬鐪熺殑涓嶅悓浜?jiǎn)锛屼互鍓嶅浣曟帴鍙楀ぇ閲忕敤鎴窐q炴帴鐨勯棶棰橈紝鐜板湪鍗磋濡傛杞繪澗鐨勬悶瀹氾紝鐪熸槸璁╀漢涓嶅緱涓嶆劅鍙癸紝瀵瑰摢銆?/p>
鎬葷粨
Windows瀹屾垚绔彛涓嶭inux epoll鎶鏈柟妗堟槸榪?涓鉤鍙頒笂瀹炵幇寮傛IO鍜岃璁″紑鍙戜竴涓ぇ瀹歸噺錛屽叿鍙墿灞曟х殑winsock紼嬪簭鎸囨湇鍔$▼搴忕殑寰堝ソ鐨勯夋嫨錛屾湰鏂囧榪?涓妧鏈殑瀹炵幇鍘熺悊鍜屽疄闄呯殑浣跨敤鏂規(guī)硶鍋氫簡(jiǎn)涓涓緇嗙殑浠嬬粛銆?/p>
@import url(http://www.shnenglu.com/CuteSoft_Client/CuteEditor/Load.ashx?type=style&file=SyntaxHighlighter.css);@import url(/css/cuteeditor.css);