C SOCKET通訊模型(七)非同步epoll

2021-08-07 18:40:55 字數 3307 閱讀 7529

不得不說為這非同步epoll模型還真是傷了神。。。主要問題就是在libaio的核心通知上,因為這東西實在太低階了,用起來還比較麻煩。我為了不再多開執行緒,實現和iocp基本相同的原理,在proc內部又用了次epoll,使其核心通知和使用者通知都能在乙個執行緒中得到相同處理。並且用map對映eventfd與收發型別的關係,使其能夠在收到event的時候,通過eventfd能直接判斷出接下來的操作。還有就是由於libaio需要將fd設定為o_direct,所以無論收發都得用自己的緩衝區,不然會導致效率大大降低。這份**有興趣自己研究,具體的不多說了,寫出來還沒測試,不知道應用於實際專案中效果如何,大牛可以自己測下

yum install libaio-devel

-lpthread -std=c++11

#include #include#include#include#include#include #include#include#include#include#include #include#include#include#include#include#define recv_events 1024

#define send_events 1024

#define proc_events 1024

#define buf_send_len 1024

#define buf_recv_len 1024

#define recv_len 128

#define send_len 128

using namespace std;

typedef unsigned long long ull;

struct client

;void* createserv(void* args);

void* proc(void* args);

using namespace std;

const int _thread_count = 8;

int _epfd;

int socksrv;

int id = 0;

epoll_event _events[recv_events] = ;

epoll_event ev[_thread_count];

mutex m;

deque_deque;

map_sockmap;

list_removelist;

mutex lock4cv2;

condition_variable cv2;

int _thread_unfinish;

int _eventfd4send[_thread_count];

int _eventfd4recv[_thread_count];

int _proc_epfd[_thread_count];

map_eventfd_type_map;

enum

;int main()

pthread_create(&tid, 0, createserv, 0);

for (int i = 0; i < _thread_count; i++)

cin.get();

cin.get();

return 0;

}bool _isfinish()

void release(int fd)

} close(fd);

}static void recv_callback(io_context_t ctx, struct iocb *iocb, long res, long res2)

void* proc(void* args)

epoll_event* e = _deque.front();

_deque.pop_front();

m.unlock();

if (e->data.fd == -1)

if (e->data.fd == socksrv)

else if (e->events == epollin)

else

}io_submit(ioctx, i, io_submit_arr);

//此處一定要加鎖。當wait還未準備好,但_isfinish剛剛檢測完時_thread_unfinish -= 1;cv2.notify_all();這兩句恰巧在之後執行,那就gg了,兩邊進入互相等待的狀態

lock4cv2.lock();

_thread_unfinish -= 1;

cv2.notify_all();

lock4cv2.unlock();

}else

io_submit(ioctx4write, i, io_submit_arr2);

}num -= r;}}

}threadevents[i].events = 0;

} }}void* createserv(void* args)

_epfd = epoll_create(recv_events);

ev[0].data.fd = socksrv;

ev[0].events = epollin | epollet;

epoll_ctl(_epfd, epoll_ctl_add, socksrv, &ev[0]);

//accept loop

while (true)

while (true)

fcntl(s, f_setfl, o_nonblock | o_direct);

client* c = new client;

posix_memalign((void**)&c->recvbuf, getpagesize(), buf_recv_len);

posix_memalign((void**)&c->sendbuf, getpagesize(), buf_send_len);

c->id = id;

c->fd = s;

id += 1;

_sockmap.insert(pair(s, c));

ev[0].data.fd = s;

ev[0].events = epollin | epollet;

epoll_ctl(_epfd, epoll_ctl_add, s, &ev[0]);

} _thread_unfinish = _thread_count;

for (int i = 0; il(lock4cv2);

cv2.wait(l, _isfinish);

for (auto iter = _removelist.begin(); iter != _removelist.end(); ++iter)

_removelist.clear();

}}

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

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

C SOCKET通訊模型(一)select

為了 簡潔,socket上那些函式的返回錯誤值我就不再捕獲了,windows平台 server.cpp define fd setsize 2048 normal.cpp 定義控制台應用程式的入口點。include stdafx.h include include include include i...

C SOCKET通訊模型(四)IOCP

相比ioevent,iocp沒有事件監聽,而是採用執行緒池管理 其實就是對使用者建立的執行緒的乙個分配管理機制,本身並不會建立多餘額外的執行緒 佇列的形式,這個系統佇列也就是所謂的完成埠,用於核心與應用層的互動。iocp沒有監聽事件數量的限制,沒有事件列表為空需要等待的問題,雖然ioevent沒有i...