我到底在忙啥呢?

 好几天没写日志了。这段时间一直感觉自己很忙,但又不知道到底忙些啥。学到了啥,反正时间花了,但好像又没啥效果。。这几天一直在网上瞎逛,下了很多的视频教程,可是下到电脑上纯粹是消耗硬盘空间,也没来得及看。。

 

工作中的很多东西还是不会,可是又不知道该从哪方面入手。linux和oracle这两方面看样子是要买几本参考资料系统的学一学,而不是盲目的在网上瞎看。网上的东西虽然很多,可很多的资料感觉都是针对有一定基础的。而我暂时还没达到那水平。

在oracle的维护方面自己好像就从零开始。。什么参数设置。环境变量设置,alert日志查看,这些对我都比较新鲜。今年注定是奋斗的一年,那么就好好把握。。希望一两年之后的你在维护方面能有一定提高。。

不管前面的路多么漫长。。还是要努力。。虽然笨点,多花点时间。相信自己,能在这行业呆下来的。。

<think>嗯,用户想了解LT模式下epoll_wait为什么会出现等现象以及如何避免。首先,我得回忆一下LT(水平触发)和ET(边缘触发)模式的区别。记得LT模式下,只要文件描述符处于就绪状态,epoll_wait就会不断通知,而ET模式只在状态变化时通知一次。这可能就是LT模式导致等的原因吧。 那为什么LT模式下会出现等呢?可能因为应用程序没有正确处理就绪的事件。比如,假设一个socket接收缓冲区有数据可读,但应用程序只读取了一部分,剩下的数据还在缓冲区里。这时候,LT模式的epoll_wait下次会再次通知这个事件,导致循环触发。如果程序没有正确处理,比如没有循环读取直到EAGAIN或EWOULDBLOCK错误,就可能不断被唤醒,造成CPU等。 接下来,用户可能想知道如何避免这种情况。解决方法应该包括确保每次事件触发时都彻底处理完数据,比如在读取时循环读取直到没有更多数据。另外,可能需要将socket设置为非阻塞模式,避免在read或write时阻塞,这样可以更高效地处理数据,防止程序卡在某个操作上,导致事件重复触发。 不过,用户提供的引用中提到ET模式效率更高,只支持非阻塞套接字。这可能意味着在LT模式下,即使使用阻塞套接字,也可能导致问题,比如未完全读取数据时,epoll_wait会持续通知,但阻塞读取可能会导致进程挂起,无法处理其他事件。所以,将socket设置为非阻塞可能是一个关键点,即使在LT模式下,也应该这样做,以避免等。 另外,引用[1]提到ET模式只支持非阻塞套接字,这可能是因为ET模式需要确保一次触发后处理所有数据,而使用非阻塞可以避免阻塞导致的事件丢失。但LT模式虽然支持阻塞套接字,但为了高效处理,还是建议使用非阻塞,并配合循环读取。 总结一下,LT模式下的等主要是由于未完全处理事件导致的,解决方法包括非阻塞IO和彻底处理事件。此外,确保每次处理事件时都清空缓冲区,避免遗留数据触发后续的epoll_wait通知。可能还需要调整事件处理逻辑,比如合并事件处理循环,或者合理管理事件注册,避免重复触发。</think>### LT模式下epoll_wait出现等现象的原因及解决方法 #### 一、根本原因分析 1. **LT模式特性** 在水平触发(LT)模式下,只要文件描述符(fd)处于就绪状态(例如socket接收缓冲区有数据未读),`epoll_wait`会**持续返回该事件**,直到就绪条件消失[^1]。例如: - 若接收缓冲区有100字节数据,但应用程序只读取50字节,剩余50字节未处理时,`epopll_wait`会再次通知该事件 - 若发送缓冲区未满时,持续调用`epoll_wait`会反复触发可写事件通知 2. **未彻底处理事件** 典型场景: ```c while (epoll_wait(epfd, events, MAX_EVENTS, timeout) > 0) { for (每个就绪事件) { if (可读事件) { read(fd, buf, 1024); // 未循环读取到EAGAIN } } } ``` 若未通过`while(read(...) > 0)`彻底读取数据,残留数据会导致后续`epoll_wait`持续触发。 #### 二、解决方法 1. **非阻塞IO强制使用** 即使使用LT模式,也应将socket设置为非阻塞模式: ```c int flags = fcntl(fd, F_GETFL, 0); fcntl(fd, F_SETFL, flags | O_NONBLOCK); ``` - 避免单次`read`/`write`因数据未处理完而阻塞后续事件处理 - 使`EAGAIN`/`EWOULDBLOCK`成为判断处理完成的明确信号 2. **彻底处理事件** ```c // 读处理示例 while (1) { ssize_t n = read(fd, buf, sizeof(buf)); if (n > 0) { // 处理数据 } else if (n == 0) { // 对端关闭连接 close(fd); break; } else if (errno == EAGAIN || errno == EWOULDBLOCK) { break; // 数据已读完 } else { // 错误处理 break; } } ``` 3. **写事件特殊处理** 对于可写事件,应采用**按需注册**策略: ```c // 需要发送数据时注册EPOLLOUT struct epoll_event ev; ev.events = EPOLLIN | EPOLLOUT; // 添加写关注 epoll_ctl(epfd, EPOLL_CTL_MOD, fd, &ev); // 发送完成后立即取消EPOLLOUT ev.events = EPOLLIN; epoll_ctl(epfd, EPOLL_CTL_MOD, fd, &ev); ``` 避免持续触发无意义的可写事件。 4. **超时参数优化** 合理设置`epoll_wait`的超时时间: ```c int timeout = active_connections > 0 ? 0 : 1000; // 有活跃连接时立即返回 epoll_wait(epfd, events, MAX_EVENTS, timeout); ``` - 当系统负载高时,适当增大超时时间减少CPU空转 - 需权衡响应延迟与CPU利用率 #### 三、性能对比指标 | 处理方式 | CPU占用率 | 吞吐量 | 编程复杂度 | |-------------------|-----------|----------|------------| | 未彻底处理+阻塞IO | 高 | 低 | 低 | | 彻底处理+非阻塞IO | 中等 | 高 | 高 | | ET模式+非阻塞IO | 低 | 最高 | 最高 |
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值