前几天和同学一起讨论EPOLLONESHOT的作用,它的功能是这样的:
对于注册了EPOLLONESHOT事件的文件描述符,操作系统最多触发其上注册的包括可读,可写,错误中的一个,且只触发一次
刚一看感觉EPOLLONESHOT咋么就是ET模式相对于LT模式的区别,反复理解之后发现原来ET和ONESHOT的区别是ET只是可读可写或错误类的某一种事件类型只能被触发一次,而不同种类的事件类型却可以触发不止一次。难道仅仅是这个区别么,如果只是这样,我感觉给给事件类型加个ONESHOT还不如只用ET呢,好像这样也并没什么大问题。
又经过仔细读之后,我发现书上在介绍EPOLLONESHOT时说其是为了应对ET模式下同种事件可能会被触发多次的情况。这下我明白了ONESHOT的作用了,但是我却更加奇怪,ET模式下咋么会同种事件被触发多次呢?
后来我想会不会是发送方发送的数据中由于一些原因导致其中的一部分和另一部分发送来的时间有很大(注意这个很大也不是很大,你懂得)的间隔.那么咋样才可能出现这种情况呢,当然你每次发送的数据越大出现这种几率的可能也就越大,所以为此我写了代码进行了测试,但是发现测了好多也没出现ET被触发多次的现象
最后我想了下会不会是因为系统默认的接收缓冲区给的太大了?于是我将缓冲区改为500字节大小,然后send一次send100000数据,果不其然,这次ET模式下,可读被触发了40多次
具体测试情况如下:
server端
#include<iostream>
#include<vector>
#include<algorithm>
#include<numeric>
#include<sys/types.h>
#include<sys/socket.h>
#include<netinet/in.h>
#include<arpa/inet.h>
#include<assert.h>
#include<stdio.h>
#include<unistd.h>
#include<errno.h>
#include<string.h>
#include<fcntl.h>
#include<sys/epoll.h>
#include<pthread.h>
using namespace std;
#define MAX_EVENT_NUMBER 1024
#define BUFFER_SIZE 10
int SUM = 0;
//设置文件描述符为非阻塞
int setnonblocking(int fd)
{
int old_option = fcn