epoll监听信号事件-signalfd

signalfd介绍
epoll+signalfd
signalfd介绍
signalfd:传统的处理信号的方式是注册信号处理函数;由于信号是异步发生的,要解决数据的并发访问,可重入问题。signalfd可以将信号抽象为一个文件描述符,当有信号发生时可以对其read,这样可以将信号的监听放到select、poll、epoll等监听队列中。当有事件触发时,有可读事件发生。
signalfd涉及API:

#include <sys/signalfd.h>
int signalfd(int fd, const sigset_t *mask, int flags);
1
2
参数fd:如果是-1则表示新建一个,不是-1并且是一个合法的signalfd表示向其添加新的信号。

参数mask:信号集合。

参数flag:内核版本2.6.27以后支持SFD_NONBLOCK、SFD_CLOEXEC。

成功返回文件描述符,返回的fd支持以下操作:read、select(poll、epoll)、close。

将感兴趣的信号加入到sigset_t中
调用signalfd(),把信号集与fd关联起来
调用sigprocmask(),把信号集添加进去,避免触发这些信号的默认处理方式
阻塞等待信号的发生并读取
与传统的处理信号的方式一样,发送多个相同的信号,只处理一次
epoll+signalfd
#include <signal.h>
#include <string>
#include <sys/epoll.h>
#include <sys/signalfd.h>
#include <unistd.h>
#include<iostream>

void signalCallBackFunc(int signalFd) {
struct signalfd_siginfo fdsiI;
std::cout << "signalCallBackFunc" << std::endl;
int s = read(signalFd, &fdsiI, sizeof(struct signalfd_siginfo));
}

int main() {
int epfd = epoll_create1(0);
sigset_t sigintMask;

sigemptyset(&sigintMask);
sigaddset(&sigintMask, SIGINT);
sigprocmask(SIG_BLOCK, &sigintMask, NULL);

int sigintfd;
sigintfd = signalfd(-1, &sigintMask, 0);

struct epoll_event sigintEvent;
sigintEvent.data.fd = sigintfd;
sigintEvent.events = EPOLLIN;

epoll_ctl(epfd, EPOLL_CTL_ADD, sigintfd, &sigintEvent);

struct epoll_event events[1024];
while (1) {
int n = epoll_wait(epfd, events, 1024, -1);

for (int i = 0; i < n; i++) {
auto returnfd = events[i].data.fd;
signalCallBackFunc(returnfd);
}
}
}
————————————————

版权声明:本文为博主原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。

原文链接:https://blog.csdn.net/qq_42956653/article/details/120443844

 

posted @ 2024-02-02 14:39  imxiangzi  阅读(94)  评论(0编辑  收藏  举报