相比ioevent,iocp沒有事件監聽,而是採用執行緒池管理(其實就是對使用者建立的執行緒的乙個分配管理機制,本身並不會建立多餘額外的執行緒)+佇列的形式,這個系統佇列也就是所謂的完成埠,用於核心與應用層的互動。iocp沒有監聽事件數量的限制,沒有事件列表為空需要等待的問題,雖然ioevent沒有ioapc裡負載均衡問題嚴重,但還是存在一定負載均衡問題,並且需要自己去做均衡策略,在iocp裡得到完美解決,採用執行緒間爭搶的模式,這是真正意義上的做到了均衡,後面epoll我也會用這個策略去做。相比ioapc,上篇所提到的ioapc的5個問題都得到解決。並且可以看出,iocp更貼近於ioevent,apc不合理之處實在太多,所以以後也要盡量避免apc的設計使用。
先說說iocp的設計思路,不知道有沒人在看ioevent的時候曾想過,有沒辦法繞過事件監聽,並且保持大體結構幾乎不變。沒錯,如果能介入wsarecv的設計的話,可以在通知事件那地方,將乙個標識放入佇列,然後讓所有等待佇列的執行緒去爭搶這個標識,那麼一定是誰閒誰得到這個標識,一直迴圈,直到隊列為空,該執行緒執行完後又保持空閒狀態,並且配合wsarecv這個非同步方法,不再需要額外執行緒,就可以實現整個迴圈,真的是把執行緒上的資源用得淋漓盡致。可能說得還比較粗糙,具體的話還需要讀者個人去研究體會。
我寫的這個**也是以簡潔為前提,所以傳送部分都寫的同步模式,如果需要用非同步傳送的話,需要在client結構中增加個狀態標識,並對傳送 接收進行區分,一起在proc中判斷並處理。非除錯請關閉伺服器端輸出,不然會執行得很慢
// iocp.cpp: 定義控制台應用程式的入口點。
//#include "stdafx.h"
#include #include#include#include#include #include #pragma comment(lib,"ws2_32.lib")
unsigned int winapi createserv(lpvoid args);
unsigned int winapi proc(lpvoid args);
using namespace std;
int _thread_count;
char buf[128];
const int _buflen = 1024;
struct client
;handle hcompport;
dword dwrecvcount = 0;
dword nflag = 0;
map_clients;
mutex m;
int main()
cin.get();
cin.get();
return 0;
}void release(client* c)
unsigned int winapi proc(lpvoid args)
//cout << "proc by:" << imemset(c->buf.buf, 0, _buflen);
send(c->s, buf, 128, 0);
}} else
}}unsigned int winapi createserv(lpvoid args)
if (lobyte(wsadata.wversion) != 2 || hibyte(wsadata.wversion) != 1)
const char chopt = 1;
setsockopt(socksrv, ipproto_tcp, tcp_nodelay, &chopt, sizeof(chopt));
int nsendbuflen = 16 * 1024 * 1024;
setsockopt(socksrv, sol_socket, so_sndbuf, (const char*)&nsendbuflen, sizeof(int));
sockaddr_in addrsrv;
addrsrv.sin_addr.s_un.s_addr = htonl(addr_any);
addrsrv.sin_family = af_inet;
addrsrv.sin_port = htons(6001);
::bind(socksrv, (sockaddr*)&addrsrv, sizeof(sockaddr));
err = listen(socksrv, somaxconn);
if (err == socket_error)
sockaddr_in remoteaddr;
int addrsize = sizeof(remoteaddr);
//accept loop
while (true) while (_clients.find(id) != _clients.end());
_clients.insert(pair(id, c));
c->id = id;
m.unlock();
if(createiocompletionport((handle)c->s,hcompport,(ulong_ptr)c,0)==0)
} }return 0;
}
C SOCKET通訊模型(一)select
為了 簡潔,socket上那些函式的返回錯誤值我就不再捕獲了,windows平台 server.cpp define fd setsize 2048 normal.cpp 定義控制台應用程式的入口點。include stdafx.h include include include include i...
C SOCKET通訊模型(七)非同步epoll
不得不說為這非同步epoll模型還真是傷了神。主要問題就是在libaio的核心通知上,因為這東西實在太低階了,用起來還比較麻煩。我為了不再多開執行緒,實現和iocp基本相同的原理,在proc內部又用了次epoll,使其核心通知和使用者通知都能在乙個執行緒中得到相同處理。並且用map對映eventfd...
高效通訊模型之 非同步通訊模型
非同步模型 非同步和同步 同步,就是在發出乙個功能呼叫時,在沒有得到結果前,呼叫不返回 非同步,當乙個非同步過程呼叫發出後,呼叫者不能立即得到呼叫結果,而是通過狀態,通知和 來通知呼叫者。通過檢查狀態來判斷非同步呼叫結果,效率會很低,因為需要週期性檢查狀態 函式和通知差不多 同步呼叫與阻塞呼叫 對於...