epool linux内核,Linux内核epoll ET/LT辨析

本文探讨了Linux内核3.10.104x86_64中epoll的ET和LT模式下事件处理的不同策略。ET模式下,丢失未处理事件;LT模式保持事件,简化编程。在高活跃连接场景,ET效率更高。大量短连接时,性能受影响。
摘要由CSDN通过智能技术生成

本文基于linux 3.10.104 x86_64内核,接上篇针对epoll ET和LT不同模式下的事件处理进行分析,对应源码位于fs/eventpoll.c。

ET和LT对于监听fd事件就绪时发送给用户的回调函数ep_send_events_proc处理有些区别:

static int ep_send_events_proc(struct eventpoll *ep, struct list_head *head,

void *priv)

{

struct ep_send_events_data *esed = priv;

int eventcnt;

unsigned int revents;

struct epitem *epi;

struct epoll_event __user *uevent;

struct wakeup_source *ws;

poll_table pt;

init_poll_funcptr(&pt, NULL);

/*

* We can loop without lock because we are passed a task private list.

* Items cannot vanish during the loop because ep_scan_ready_list() is

* holding "mtx" during this call.

*/

for (eventcnt = 0, uevent = esed->events;

!list_empty(head) && eventcnt < esed->maxevents;) {

epi = list_first_entry(head, struct epitem, rdllink);

/*

* Activate ep->ws before deactivating epi->ws to prevent

* triggering auto-suspend here (in case we reactive epi->ws

* below).

*

* This could be rearranged to delay the deactivation of epi->ws

* instead, but then epi->ws would temporarily be out of sync

* with ep_is_linked().

*/

ws = ep_wakeup_source(epi);

if (ws) {

if (ws->active)

__pm_stay_awake(ep->ws);

__pm_relax(ws);

}

list_del_init(&epi->rdllink);

revents = ep_item_poll(epi, &pt);

/*

* If the event mask intersect the caller-requested one,

* deliver the event to userspace. Again, ep_scan_ready_list()

* is holding "mtx", so no operations coming from userspace

* can change the item.

*/

if (revents) {

if (__put_user(revents, &uevent->events) ||

__put_user(epi->event.data, &uevent->data)) {

list_add(&epi->rdllink, head);

ep_pm_stay_awake(epi);

return eventcnt ? eventcnt : -EFAULT;

}

eventcnt++;

uevent++;

if (epi->event.events & EPOLLONESHOT)

epi->event.events &= EP_PRIVATE_BITS;

else if (!(epi->event.events & EPOLLET)) {

/*

* If this file has been added with Level

* Trigger mode, we need to insert back inside

* the ready list, so that the next call to

* epoll_wait() will check again the events

* availability. At this point, no one can insert

* into ep->rdllist besides us. The epoll_ctl()

* callers are locked out by

* ep_scan_ready_list() holding "mtx" and the

* poll callback will queue them in ep->ovflist.

*/

list_add_tail(&epi->rdllink, &ep->rdllist);

ep_pm_stay_awake(epi);

}

}

}

return eventcnt;

}

重点看第60行分支处理,在非ET模式下,仍然会将该含就绪事件的fd对应epitem重新插入回就绪列表,以便epoll_wait下一次调用继续处理。

当用户场景下有大量短连接时,epoll对于红黑树频繁的插入和删除操作也会有性能蜕化;对于ET和LT模式的使用,LT对于未处理的事件不会丢掉,使用更简单,ET下若用户漏掉处理,就绪事件则会丢失掉,编程处理上有一定复杂性;当用户场景下处理大量fd但仅有少量活跃连接时,epoll则相对更高效。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值