📝个人主页🌹:Eternity._ ⏩收录专栏⏪:Linux “ 登神长阶 ” 🌹🌹期待您的关注 🌹🌹


❀ Linux高级IO
- 多路转接:poll
-
- poll函数接口
- poll优缺点
- 多路转接:epoll
-
- epoll的相关系统调用
- epoll工作原理
- epoll的优点
- epoll工作方式
- 理解ET模式和非阻塞文件描述符
- 总结
前言:在现代的Linux网络编程中,高效地管理多个并发连接是服务器性能优化的核心挑战之一。为了应对这一挑战,Linux操作系统提供了多种I/O多路复用技术,其中poll和epoll作为两种重要的机制,在提升系统资源利用率和处理效率方面发挥着关键作用。
poll 作为早期的一种多路转接方案,解决了select函数中文件描述符数量有限和每次调用都需要重新设置的问题。然而,随着网络技术的发展和服务器负载的不断增加,poll在某些场景下也显露出了性能瓶颈。此时,epoll作为Linux 2.6内核引入的一种更为高效的I/O多路复用机制,凭借其出色的性能和灵活性,逐渐成为高性能服务器应用的首选。
epoll 不仅克服了poll和select的诸多限制,如文件描述符数量的限制和每次调用时的效率问题,还引入了边缘触发(Edge Triggered)的工作模式,进一步提高了应用程序的响应速度和系统资源的利用率。通过只通知那些真正发生了I/O事件的文件描述符,epoll显著减少了不必要的上下文切换和CPU资源的浪费。
让我们携手踏上这段探索之旅,一同揭开Linux高级I/O的神秘面纱。
多路转接:poll
在Linux系统中,多路转接技术是一种重要的I/O处理机制,它允许单个线程同时监控多个文件描述符(例如套接字)上的事件,从而有效地管理多个并发连接。由于poll与之前所提到过的select有许多相似之处,所以我们对于poll将只进行简单的介绍
poll函数接口
#include <poll.h>
int poll(struct pollfd *fds, nfds_t nfds, int timeout);
// pollfd结构
struct pollfd
{
int fd; /* file descriptor */
short events; /* requested events */
short revents; /* returned events */
};
参数说明:
- fds是一个poll函数监听的结构列表,每一个元素中,包含了三部分内容:文件描述符、监听的事件集合、 返回的事件集合
- nfds表示fds数组的长度
- timeout表示poll函数的超时时间,单位是毫秒(ms)
events和revents的取值:
返回结果:
- 返回值小于0,表示出错
- 返回值等于0,表示poll函数等待超时
- 返回值大于0,表示poll由于监听的文件描述符就绪而返回
注意:poll中socket就绪条件和select是一样的
poll_server.hpp:
#pragma once
#include <iostream>
#include <string>
#include <poll.h>
#include \”Log.hpp\”
#include \”Socket.hpp\”
using namespace Net_Work;
const static int gdefaultport = 8888;
const static int gbacklog = 8;
const int gnum = 1024;
class PollServer
{
private:
void HandlerEvent()
{
for (int i = 0; i < _num; i++)
{
if (_rfds[i].fd == –1)
continue;
// 合法的fd
// 读事件分两种,一类是新链接的到来,一类是新数据的到来
int fd = _rfds[i].fd;
short revent = _rfds[i].revents;
if (revent & POLLIN)
{
// 读事件就绪 -> 新链接的到来
if (fd == _listensock->GetSocket(



