Some parameters, struct and return values about epoll

本文深入解析了Linux下高效I/O多路复用技术epoll的工作原理及使用方法,包括epoll_create、epoll_ctl和epoll_wait等核心函数的详细说明,通过官方示例展示了如何在实际代码中应用epoll进行事件监听。

#include <sys/epoll.h>

int epoll_create(int size);

int epoll_create1(int flags);

--When you program on linux kernel version higher than 2.6.8, you should ignore the parameter "size", you should give the paramater bigger than 0 sitll. The parameter is the file descriptor and can do dynamically allocation. So you should just give a bigger than 0 parameter to be compatible for lower version of linux kernel.

--in epoll_create1(), if the "flags" is 0, it is equal to epoll_create() except for the obsolete size abandonment. "flags" can be EPOLL_CLOEXEC, check O_CLOEXEC to understand EPOLL_CLOEXEC.

--return values: Nonnegative number (actually it's fd) for success, -1 for failure and please check error codes.

 

int epoll_ctl(int epfd, int op, int fd, struct epoll_event *event);

--There is 3 kinds of op values:

1)  EPOLL_CTL_ADD means register fd(file descriptor) into epfd and associate event with fd.

2)  EPOLL_CTL_MOD means modify the relationship between fd and event.

3)  EPOLL_CTL_DEL means the deletion of fd in epfd, event can be ignored and it can be NULL.

--As for struct epoll_event:

typedef union epoll_data {

    void *ptr;

    int fd;

    uint32_t u32;

    uint64_t u64;

} epoll_data_t;

struct epoll_event {

    uint32_t events; /* Epoll events */

    epoll_data_t data; /* User data variable */

};

--The paramater events has forwads events:

EPOLLIN: while the fd it assciates can do read() operates

EPOLLOUT: write() operates

EPOLLRDHUP: (since linux 2.6.17)when socket close, or half close write part(when you use Edge-Triggered, this identification is good for test codes to check closing).

EPOLLPRI: when read() can do urgent data

EPOLLERR: while the file which it associate has something wrong, epoll_wait() will always wait this event, it is not a identification which must be set

EPOLLHUP: means hang up. epoll_wait() will always wait for this event, it is not a identification which must be set. When socket read data from somewhere(pipping or socket), this event is just identifying this is the end of reading(EOF). Any valid data is compeletely read, after that, it will return 0 for any read operation (EOF).

EPOLLET: set the file descriptor to Edge-Trigger, the default is Level-Triggered

EPOLLONESHOT: (since linux 2.6.17) set file descriptor to once mode. It means, it will be one time for epoll_wait() to catch  the event, after that you must call epoll_ctl() again to set it again.

return values: 0 for success, -1 for failuer and errno:

EBADF - epfd or fd is invalid

EEXIST - op is EPOLL_CTL_ADD, but the fd you want to register is already registered

EINVAL - epdf is not a epoll descriptor, or epfd is equal to fd, or op parameter illegal

ENOENT - op is POLL_CTL_MOD or POLL_CTL_DEL, but fd hasn't been registered into epoll.

ENOMEM - not enuf cache

EPERM - the objective fd doesn't support epoll

 

int epoll_wait(int epfd, struct epoll_event *events, int maxevents, int timeout);

int pepoll_wait(int epfd, struct epoll_event *events, int maxevents, int timeout, const sigset_t *sigmask);

--epoll_wait()is called for waiting for events in epfd, events point to stack area of events which caller can use. maxevents tell kernel the number of events and must larger than 0. time out is to formulate the blocking time(millisecond) of epoll_wait() and block until forward conditions:

1)  a fd trigger a event

2)  is interrupt by a signal handle function or timeout

if(timeout == -1)  forever waiting(block)

if(timeout == 0) return even if no events

--As for epoll_pwait()

ready = epoll_pwait(epfd, &events, maxevents, timeout, &sigmask);

at interior it is equal to:

pthread_sigmask(SIG_SETMASK, &sigmask, &origmask);

ready = epoll_wait(epfd, &events, maxevents, timeout);

pthread_sigmask(SIG_SETMASK, &origmask, NULL);

--Thus if &sigmask is NULL, it is equal to epoll_wait()

return values:

>0: numbers of ready IO events

=0: timeout

-1: failure and please check the error code:

EBADF - epfd is a invalid fd

EFAULT - no access authority of cache which pointer events point to

EINRE - this calling is interrupted by signal.

EINVAL - epfd is not an epoll descriptor, or maxevents <= 0

 

------OFFICIAL DEMO------

#define MAX_EVENTS 10

struct epoll_event ev, events[MAX_EVENTS];

int listen_sock, conn_sock, nfds, epollfd;

/* Code to set up listening socket, 'listen_sock', * (socket(), bind(), listen()) omitted */

epollfd = epoll_create1( 0 );

if ( epollfd == -1 ) {

    perror( "epoll_create1" );

    exit( EXIT_FAILURE );

}

ev.events = EPOLLIN;

ev.data.fd = listen_sock;

if ( epoll_ctl( epollfd, EPOLL_CTL_ADD, listen_sock, &ev ) == -1 ) {

    perror( "epoll_ctl: listen_sock" );

    exit( EXIT_FAILURE );

}

for (;; ) {

    nfds = epoll_wait( epollfd, events, MAX_EVENTS, -1 );

    if ( nfds == -1 ) {

        perror( "epoll_wait" );

        exit( EXIT_FAILURE );

    }

    for ( n = 0; n < nfds; ++n ) {

        if ( events[n].data.fd == listen_sock ) {

            conn_sock = accept( listen_sock, (struct sockaddr *) &local, &addrlen );

            if ( conn_sock == -1 ) {

                perror( "accept" );

                exit( EXIT_FAILURE );

            }

            setnonblocking( conn_sock );

            ev.events = EPOLLIN | EPOLLET;

            ev.data.fd = conn_sock;

            if ( epoll_ctl( epollfd, EPOLL_CTL_ADD, conn_sock, &ev ) == -1 ) {

                perror( "epoll_ctl: conn_sock" );

                exit( EXIT_FAILURE );

            }

        } else {

            do_use_fd( events[n].data.fd );

        }

    }

}


 

【轴承故障诊断】加权多尺度字典学习模型(WMSDL)及其在轴承故障诊断上的应用(Matlab代码实现)内容概要:本文介绍了加权多尺度字典学习模型(WMSDL)在轴承故障诊断中的应用,并提供了基于Matlab的代码实现。该模型结合多尺度分析与字典学习技术,能够有效提取轴承振动信号中的故障特征,提升故障识别精度。文档重点阐述了WMSDL模型的理论基础、算法流程及其在实际故障诊断中的实施步骤,展示了其相较于传统方法在特征表达能力和诊断准确性方面的优势。同时,文中还提及该资源属于一个涵盖多个科研方向的技术合集,包括智能优化算法、机器学习、信号处理、电力系统等多个领域的Matlab仿真案例。; 适合人群:具备一定信号处理和机器学习基础,从事机械故障诊断、工业自动化、智能制造等相关领域的研究生、科研人员及工程技术人员。; 使用场景及目标:①学习并掌握加权多尺度字典学习模型的基本原理与实现方法;②将其应用于旋转机械的轴承故障特征提取与智能诊断;③结合实际工程数据复现算法,提升故障诊断系统的准确性和鲁棒性。; 阅读建议:建议读者结合提供的Matlab代码进行实践操作,重点关注字典学习的训练过程与多尺度分解的实现细节,同时可参考文中提到的其他相关技术(如VMD、CNN、BILSTM等)进行对比实验与算法优化。
【硕士论文复现】可再生能源发电与电动汽车的协同调度策略研究(Matlab代码实现)内容概要:本文档围绕“可再生能源发电与电动汽车的协同调度策略研究”展开,旨在通过Matlab代码复现硕士论文中的核心模型与算法,探讨可再生能源(如风电、光伏)与大规模电动汽车接入电网后的协同优化调度方法。研究重点包括考虑需求侧响应的多时间尺度调度、电动汽车集群有序充电优化、源荷不确定性建模及鲁棒优化方法的应用。文中提供了完整的Matlab实现代码与仿真模型,涵盖从场景生成、数学建模到求解算法(如NSGA-III、粒子群优化、ADMM等)的全过程,帮助读者深入理解微电网与智能电网中的能量管理机制。; 适合人群:具备一定电力系统基础知识和Matlab编程能力的研究生、科研人员及从事新能源、智能电网、电动汽车等领域技术研发的工程人员。; 使用场景及目标:①用于复现和验证硕士论文中的协同调度模型;②支撑科研工作中关于可再生能源消纳、电动汽车V2G调度、需求响应机制等课题的算法开发与仿真验证;③作为教学案例辅助讲授能源互联网中的优化调度理论与实践。; 阅读建议:建议结合文档提供的网盘资源下载完整代码,按照目录顺序逐步学习各模块实现,重点关注模型构建逻辑与优化算法的Matlab实现细节,并通过修改参数进行仿真实验以加深理解。
### Linux `epoll`机制及其内部结构 #### epollfd 结构体定义 在Linux操作系统中,`epoll`是一种高效的I/O事件通知方式。其核心在于能够处理大量文件描述符的同时保持较低的资源消耗。为了实现这一点,内核引入了一种新的数据结构——红黑树来存储感兴趣的文件描述符集合,并通过就绪列表记录已准备好的连接。 具体来说,在Linux内核源码(v6.0)中并没有直接名为`epollfd`的数据结构;实际上,与之最接近的概念是由`struct eventpoll`表示的对象[^3]。该对象负责管理所有注册到特定`epoll`实例上的文件描述符以及它们的状态变化情况: ```c struct eventpoll { /* ...其他字段... */ struct rb_root rbr; // 红黑树根节点用于保存监听的socket struct list_head rdllist; // 就绪链表用来快速访问已经准备好IO操作的项 wait_queue_head_t wq; // 等待队列当没有任何事件发生时进程会在此处休眠直到有新事件到来唤醒它 }; ``` 对于应用程序而言,“`epollfd`”通常指的是通过系统调用`epoll_create()`创建并返回的一个特殊类型的文件描述符。此FD作为接口让开发者可以向其中添加/删除关注的目标套接字或管道等实体,并查询哪些成员处于可读写状态以便进一步处理。 #### 使用方法示例 下面给出一段简单的C语言程序片段展示了如何利用上述提到的功能完成基本的任务: ```c #include <sys/epoll.h> #include <unistd.h> int main() { int epfd = epoll_create1(EPOLL_CLOEXEC); // 创建一个新的epoll实例 struct epoll_event ev; ev.events = EPOLLIN | EPOLLET; // 设置关心的事件类型(边沿触发模式) // 假设sockfd是我们想要监控的某个网络连接对应的文件描述符... if (epoll_ctl(epfd, EPOLL_CTL_ADD, sockfd, &ev)) { perror("Error adding socket to epoll"); close(epfd); return -1; } while(true){ struct epoll_event events[10]; int nfds = epoll_wait(epfd, events, 10, -1); for(int n=0;n<nfds;++n){ // 处理events[n].data.fd所指向的那个具体的文件描述符上发生的event } } close(epfd); } ``` 这段代码首先建立了自己的`epoll`监视器(`epfd`),接着把目标文件描述符加入到了这个监视器里去等待输入到达。之后进入无限循环不断轮询是否有任何活动的发生,一旦发现则立即做出响应。
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值