epoll 和select

epoll 水平触发和边缘触发的区别

EPOLLLT——水平触发
EPOLLET——边缘触发

epoll有EPOLLLT和EPOLLET两种触发模式,LT是默认的模式,ET是“高速”模式。LT模式下,只要这个fd还有数据可读,每次 epoll_wait都会返回它的事件,提醒用户程序去操作,而在ET(边缘触发)模式中,它只会提示一次,直到下次再有数据流入之前都不会再提示了,无 论fd中是否还有数据可读。所以在ET模式下,read一个fd的时候一定要把它的buffer读光,也就是说一直读到read的返回值小于请求值,或者 遇到EAGAIN错误。

 

select 最大限制为1024解析

   Linux下,select下模型为:__FD_SETSIZE 默认最大为1024,一个int占用4个byte,也就是32个bit,所以使用了一个int数组大小为32位来表示了我们要操作的fd的数值,每个bit代表了一个handle数值,需要注意的问题是,这里的最大为1024,如果handle数值为1025是不能处理的(而且很容易导致破坏堆栈),不是说可以容纳1024个网络客户端句柄,而是最大的handle数值为1024,再算上系统本身使用的stdout,stdin, stderr默认的3个,因此最多也就是1021个,再算上程序打开的文件句柄等等,实际上使用可能要比1024少上好多。另外,ulimit对每个进程打开的句柄也有限制。当然可以通过修改内核来增大,但是原则上不推荐修改过大,这是因为过大的数目会对性能造成很大影响,所以推荐使用epoll来处理大数目handle数值。

    

    

/* fd_set for select and pselect.  */

typedef struct
{
/* XPG4.2 requires this member name. Otherwise avoid the name
from the global namespace. */
#ifdef __USE_XOPEN
__fd_mask fds_bits[__FD_SETSIZE / __NFDBITS];
# define __FDS_BITS(set) ((set)->fds_bits)
#else
__fd_mask __fds_bits[__FD_SETSIZE / __NFDBITS];
# define __FDS_BITS(set) ((set)->__fds_bits)
#endif
} fd_set;

 

#ifdef FD_SETSIZE
#define __DARWIN_FD_SETSIZE FD_SETSIZE
#else /* !FD_SETSIZE */
#define __DARWIN_FD_SETSIZE 1024
#endif /* FD_SETSIZE */
#define __DARWIN_NBBY 8 /* bits in a byte */
#define __DARWIN_NFDBITS (sizeof(__int32_t) * __DARWIN_NBBY) /* bits per mask */
#define __DARWIN_howmany(x, y) ((((x) % (y)) == 0) ? ((x) / (y)) : (((x) / (y)) + 1)) /* # y's == x bits? */

__BEGIN_DECLS
typedef struct fd_set {
  __int32_t fds_bits[__DARWIN_howmany(__DARWIN_FD_SETSIZE, __DARWIN_NFDBITS)];
} fd_set;
__END_DECLS

 

 

 处理使用ulimit修改限制以为也可以通过函数来getrlimit和setrlimit修改:

 

getrlimit和setrlimit的使用也很简单,manpage里有很清楚的描述。
int getrlimit(int resource, struct rlimit *rlim);
int setrlimit(int resource, const struct rlimit *rlim);
需要注意的是你在setrlimit,需要检查是否成功来判断新值有没有超过hard limit。如下例:
if (getrlimit(RLIMIT_CORE, &rlim)==0) {

rlim_new.rlim_cur = rlim_new.rlim_max = RLIM_INFINITY;
if (setrlimit(RLIMIT_CORE, &rlim_new)!=0) {
/* failed. try raising just to the old max */
rlim_new.rlim_cur = rlim_new.rlim_max =
rlim.rlim_max;
(void) setrlimit(RLIMIT_CORE, &rlim_new);
}

}

 

转载于:https://www.cnblogs.com/fvsfvs123/p/4362562.html

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值