C SOCKET通訊模型(四)IOCP

2021-08-07 13:02:09 字數 2496 閱讀 2234

相比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...

高效通訊模型之 非同步通訊模型

非同步模型 非同步和同步 同步,就是在發出乙個功能呼叫時,在沒有得到結果前,呼叫不返回 非同步,當乙個非同步過程呼叫發出後,呼叫者不能立即得到呼叫結果,而是通過狀態,通知和 來通知呼叫者。通過檢查狀態來判斷非同步呼叫結果,效率會很低,因為需要週期性檢查狀態 函式和通知差不多 同步呼叫與阻塞呼叫 對於...