结论
总体来看两者差距不大,甚至LT比ET还稍微好一点。两者区别:epoll的句柄是否对缓冲区的变化进行状态变化。
绑定的单核cpu 16GB内存 centos 7.0 gcc 版本 4.8.5
使用taskset绑定为单核,ab压测
taskset -cp 6 10714
ab -n 50000 -k 127.0.0.1/
ET:
Requests per second: 4974.68 [#/sec] (mean)
Time per request: 0.201 [ms] (mean)
Time per request: 0.201 [ms] (mean, across all concurrent requests)
Requests per second: 5013.28 [#/sec] (mean)
Time per request: 0.199 [ms] (mean)
Time per request: 0.199 [ms] (mean, across all concurrent requests)
LT:
Requests per second: 5104.07 [#/sec] (mean)
Time per request: 0.196 [ms] (mean)
Time per request: 0.196 [ms] (mean, across all concurrent requests)
Requests per second: 5024.95 [#/sec] (mean)
Time per request: 0.199 [ms] (mean)
Time per request: 0.199 [ms] (mean, across all concurrent requests)
代码
1 LT代码
/*
* 编译:g++ -o epoll-lt epoll-lt.cpp
* 运行: ./epoll-lt
* 测试:curl -v localhost
*/
#include <arpa/inet.h>
#include <errno.h>
#include <fcntl.h>
#include <netinet/in.h>
#include <signal.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <sys/epoll.h>
#include <sys/socket.h>
#include <unistd.h>
#include <map>
#include <string>
using namespace std;
bool output_log = true;
#define exit_if(r, ...) \
if (r) { \
printf(__VA_ARGS__); \
printf("%s:%d error no: %d error msg %s\n", __FILE__, __LINE__, errno, strerror(errno)); \
exit(1); \
}
void setNonBlock(int fd) {
int flags = fcntl(fd, F_GETFL, 0);
exit_if(flags < 0, "fcntl failed");
int r = fcntl(fd, F_SETFL, flags | O_NONBLOCK);
exit_if(r < 0, "fcntl failed");
}
void updateEvents(int efd, int fd, int events, int op) {
struct epoll_event ev;
memset(&ev, 0, sizeof(ev));
ev.events = events;
ev.data.fd = fd;
printf("%s fd %d events read %d write %d\n", op == EPOLL_CTL_MOD ? "mod" : "add", fd, ev.events & EPOLLIN, ev.events & EPOLLOUT);
int r = epoll_ctl(efd, op, fd, &ev);
exit_if(r, "epoll_ctl failed");
}
void handleAccept(int efd, int fd) {
struct sockaddr_in raddr;
socklen_t rsz = sizeof(raddr);
int cfd = accept(fd, (struct sockaddr *) &raddr, &rsz);
exi