UNIX网络编程——epoll的ET/LT模式注意点

2024-08-28 04:18

本文主要是介绍UNIX网络编程——epoll的ET/LT模式注意点,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

epoll模型有两种工作模式,ET和LT两种模式下都有一些细节值得注意,以下是一些思考:
一、ET模式下
Q1:调用accept时,到底TCP完成队列里有多少个已经建立好的连接?
这里又得分情况来说:
  • 没有连接。这种情况发生在TCP连接被客户端夭折,即在服务端调用accept之前客户端给出一个RST该RST导致刚刚建立好的连接从服务器端的TCP完成队列中被移出。源自berkeley的实现会在内核处理该事件,并不会将该事件通知给服务程序,如果套接口被设置为阻塞模式,就会导致accept函数被阻塞,程序挂起,一直要等到下一个连接到来,这也是为什么采用非阻塞的accept的原因;其他的实现通常会返回ECONNABORTED或EPROTO错误。

解决方法采用非阻塞的accept,在accept返回后处理ECONNABORTED、EPROTO、EINTR错误。

  • 一个以上的连接。一个连接很容易理解,多个连接的情况出现在有多个连接请求同时到达的情况,由于是边缘触发,epoll_wait只返回一次,然后调用accept处理一个请求这会导致TCP完成队列中依然存在连接未被处理。

解决办法:

1):将该套接口设置为非阻塞模式,然后将accept用while循环包住,处理完TCP完成队列中的所有连接再跳出循环。

2):将accept放入一个单独的线程中,这样还可以采用阻塞模式。


Q2:read函数应当如何处理?

read函数有可能不能够一次将内核缓冲的数据读完,由于采用的ET模式,epoll_wait不会因为内核缓冲区还有数据而继续读取。这就会导致内核数据不能及时、完全地读到服务程序。


解决办法将套接口设置为非阻塞,再用while循环包住read一直读到产生EAGAIN错误,采用非阻塞套接口的原因在于防止read被阻塞住。网上看见有的朋友说也可以采用阻塞套接口,判断read的返回值是否小于期望值,小于就证明数据读完,但是个人认为这里存在一个临界情况,比如内核缓冲有2048字节,期望读1024字节,读完第二次后read返回的是1024,等于期望值,于是再读,但此时内核已经没有数据,于是read被阻塞(自个的思考,不知有务否)。

Q3:写缓冲区什么时候可以导致epoll_wait函数返回可写状态?

个人对这个问题不是很清楚,按资料说法是该缓冲区从不可写变为可写则返回,那么该套接口刚创建的时候处于可写状态,是否会导致一直返回不了可写状态,也就是说第一次永远返回不了,因为没有任何调用会使该套接口从不可写变为可写。

另外,写的时候还有些什么要注意的么?

二、LT模式下

Q1:accept函数

accept函数同样存在连接被夭折的情况,和ET模式下类似。但这种模式下不会存在处理不完多个请求的情况。因为只要有连接存在TCP完成队列中,epoll_wait就会一直返回。

Q2:read函数

同样可以避免因为一次读不完内核缓冲区的数据的情况。

Q3:当内核写缓冲空闲时,可写状态会一直返回,如何处理?(这个曾是tencent的一个面试题)

A1:不将可写条件加入epoll集中,采用非阻塞I/O,有数据可写时,直接写,如果返回是EAGAIN,则将可写加入epoll集中,写完后移出。


通常都是写失败情况下,才会将写加入epoll中操作。

这篇关于UNIX网络编程——epoll的ET/LT模式注意点的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/1113702

相关文章

Redis Cluster模式配置

《RedisCluster模式配置》:本文主要介绍RedisCluster模式配置,本文给大家介绍的非常详细,对大家的学习或工作具有一定的参考借鉴价值,需要的朋友参考下吧... 目录分片 一、分片的本质与核心价值二、分片实现方案对比 ‌三、分片算法详解1. ‌范围分片(顺序分片)‌2. ‌哈希分片3. ‌虚

RabbitMQ工作模式中的RPC通信模式详解

《RabbitMQ工作模式中的RPC通信模式详解》在RabbitMQ中,RPC模式通过消息队列实现远程调用功能,这篇文章给大家介绍RabbitMQ工作模式之RPC通信模式,感兴趣的朋友一起看看吧... 目录RPC通信模式概述工作流程代码案例引入依赖常量类编写客户端代码编写服务端代码RPC通信模式概述在R

Linux网络配置之网桥和虚拟网络的配置指南

《Linux网络配置之网桥和虚拟网络的配置指南》这篇文章主要为大家详细介绍了Linux中配置网桥和虚拟网络的相关方法,文中的示例代码讲解详细,感兴趣的小伙伴可以跟随小编一起学习一下... 一、网桥的配置在linux系统中配置一个新的网桥主要涉及以下几个步骤:1.为yum仓库做准备,安装组件epel-re

SQL Server身份验证模式步骤和示例代码

《SQLServer身份验证模式步骤和示例代码》SQLServer是一个广泛使用的关系数据库管理系统,通常使用两种身份验证模式:Windows身份验证和SQLServer身份验证,本文将详细介绍身份... 目录身份验证方式的概念更改身份验证方式的步骤方法一:使用SQL Server Management S

python如何下载网络文件到本地指定文件夹

《python如何下载网络文件到本地指定文件夹》这篇文章主要为大家详细介绍了python如何实现下载网络文件到本地指定文件夹,文中的示例代码讲解详细,感兴趣的小伙伴可以跟随小编一起学习一下...  在python中下载文件到本地指定文件夹可以通过以下步骤实现,使用requests库处理HTTP请求,并结合o

Linux高并发场景下的网络参数调优实战指南

《Linux高并发场景下的网络参数调优实战指南》在高并发网络服务场景中,Linux内核的默认网络参数往往无法满足需求,导致性能瓶颈、连接超时甚至服务崩溃,本文基于真实案例分析,从参数解读、问题诊断到优... 目录一、问题背景:当并发连接遇上性能瓶颈1.1 案例环境1.2 初始参数分析二、深度诊断:连接状态与

Redis高可用-主从复制、哨兵模式与集群模式详解

《Redis高可用-主从复制、哨兵模式与集群模式详解》:本文主要介绍Redis高可用-主从复制、哨兵模式与集群模式的使用,具有很好的参考价值,希望对大家有所帮助,如有错误或未考虑完全的地方,望不吝... 目录Redis高可用-主从复制、哨兵模式与集群模式概要一、主从复制(Master-Slave Repli

Python 异步编程 asyncio简介及基本用法

《Python异步编程asyncio简介及基本用法》asyncio是Python的一个库,用于编写并发代码,使用协程、任务和Futures来处理I/O密集型和高延迟操作,本文给大家介绍Python... 目录1、asyncio是什么IO密集型任务特征2、怎么用1、基本用法2、关键字 async1、async

一文带你搞懂Redis Stream的6种消息处理模式

《一文带你搞懂RedisStream的6种消息处理模式》Redis5.0版本引入的Stream数据类型,为Redis生态带来了强大而灵活的消息队列功能,本文将为大家详细介绍RedisStream的6... 目录1. 简单消费模式(Simple Consumption)基本概念核心命令实现示例使用场景优缺点2

Java并发编程之如何优雅关闭钩子Shutdown Hook

《Java并发编程之如何优雅关闭钩子ShutdownHook》这篇文章主要为大家详细介绍了Java如何实现优雅关闭钩子ShutdownHook,文中的示例代码讲解详细,感兴趣的小伙伴可以跟随小编一起... 目录关闭钩子简介关闭钩子应用场景数据库连接实战演示使用关闭钩子的注意事项开源框架中的关闭钩子机制1.