使用 epoll 進行網絡異步編程(大量并發連接情況)
通常的TCP編程都是每個 進程/線程 對應一個連接。但是實際應用中常常是大量的連接并發連接到一個進程/線程上來。這樣我們就需要網絡I/O的多路復用,之前用的較多的是 select和poll。select 和 poll的時間復雜度是 O(n), 而本文將介紹的epoll時間復雜度是 O(1),epoll是基于事件的,而select模型是基于輪詢的。這樣如果有大量連接的話 epoll 的優勢顯而易見。
下面介紹使用方法:
1)創建一個 epoll 的 descriptor
epfd = epoll_create(EPOLL_QUEQU_LEN);
說明:
EPOLL_QUEUE_LEN 是epoll的最大連接數。epoll_create()函數的返回值是一個指向epoll的文件描述符,使用完成后需要使用 close()關掉。
2)創建完成后可以使用如下方式來調用:
static struct epoll_event ev;
int client_sock;
ev.events = EPOLLIN | EPOLLPRI | EPOLLERR | EPOLLHUP
ev.data.fd = client_sock;
int res = epoll_ctl(epfd, EPOLL_CTL_ADD, client_sock, &ev);
說明:
ev是epoll參數的結構體,用于配置epoll,EPOLL_CTL_ADD 是說將socket添加到epoll中去。
3)接下來程序就可以等待事件發生然后由內核來調用相應的回調函數了。
while (1) {
// wait for something to do…
int nfds = epoll_wait(epfd, events,
MAX_EPOLL_EVENTS_PER_RUN,
EPOLL_RUN_TIMEOUT);
if (nfds < 0) die("Error in epoll_wait!");
// for each ready socket
for(int i = 0; i < nfds; i++) {
int fd = events[i].data.fd;
handle_io_on_socket(fd);
}
}
來自:http://www.linuxpig.com/category/%E7%94%9F%E4%BA%A7%E7%8E%AF%E5%A2%83linux%E6%9C%8D%E5%8A%A1%E5%99%A8/