Linux新的API signalfd、timerfd、eventfd使用说明

发表于:2016-10-24 09:38

字体: | 上一篇 | 下一篇 | 我要投稿

 作者:lvyilong316    来源:51Testing软件测试网采编

  三种新的fd加入linux内核的的版本:
  signalfd:2.6.22
  timerfd:2.6.25
  eventfd:2.6.22
  三种fd的意义:
  lsignalfd
  传统的处理信号的方式是注册信号处理函数;由于信号是异步发生的,要解决数据的并发访问,可重入问题。signalfd可以将信号抽象为一个文件描述符,当有信号发生时可以对其read,这样可以将信号的监听放到select、poll、epoll等监听队列中。
  ltimerfd
  可以实现定时器的功能,将定时器抽象为文件描述符,当定时器到期时可以对其read,这样也可以放到监听队列的主循环中。
  leventfd
  实现了线程之间事件通知的方式,也可以用于用户态和内核通信。eventfd的缓冲区大小是sizeof(uint64_t);向其write可以递增这个计数器,read操作可以读取,并进行清零;eventfd也可以放到监听队列中,当计数器不是0时,有可读事件发生,可以进行读取。
  三种新的fd都可以进行监听,当有事件触发时,有可读事件发生。
  signalfd涉及API:
  点击(此处)折叠或打开
  #include <sys/signalfd.h>
  int signalfd(int fd, const sigset_t *mask, int flags);
  参数fd:如果是-1则表示新建一个,如果是一个已经存在的则表示修改signalfd所关联的信号;
  参数mask:信号集合;
  参数flag:内核版本2.6.27以后支持SFD_NONBLOCK、SFD_CLOEXEC;
  成功返回文件描述符,返回的fd支持以下操作:read、select(poll、epoll)、close
  例子
#include <sys/signalfd.h>
#include <signal.h>
#include <unistd.h>
#include <stdlib.h>
#include <stdio.h>
#define handle_error(msg) \
do { perror(msg); exit(EXIT_FAILURE); } while (0)
int main(int argc, char *argv[])
{
sigset_t mask;
int sfd;
struct signalfd_siginfo fdsi;
ssize_t s;
sigemptyset(&mask);
sigaddset(&mask, SIGINT);
sigaddset(&mask, SIGQUIT);
if (sigprocmask(SIG_BLOCK, &mask, NULL) == -1)
handle_error("sigprocmask");
sfd = signalfd(-1, &mask, 0);
if (sfd == -1)
handle_error("signalfd");
for (;;) {
s = read(sfd, &fdsi, sizeof(struct signalfd_siginfo));
if (s != sizeof(struct signalfd_siginfo))
handle_error("read");
if (fdsi.ssi_signo == SIGINT) {
printf("Got SIGINT\n");
} else if (fdsi.ssi_signo == SIGQUIT) {
printf("Got SIGQUIT\n");
exit(EXIT_SUCCESS);
} else {
printf("Read unexpected signal\n");
}
}
}
  L17-L21:将感兴趣的信号加入到sigset_t中;
  L24:调用signalfd,把信号集与fd关联起来,第一个参数为-1表示新建一个signalfd,不是-1并且是一个合法的signalfd表示向其添加新的信号。
  L29:阻塞等待信号的发生并读取。根据读取的结果可以知道发生了什么信号。
  timerfd涉及的API
  #include <sys/timerfd.h>
  int timerfd_create(int clockid, int flags);
  int timerfd_settime(int fd, int flags, const struct itimerspec *new_value,struct itimerspec *old_value);
  int timerfd_gettime(int fd, struct itimerspec *curr_value);
  timerfd_create:创建一个timerfd;返回的fd可以进行如下操作:read、select(poll、epoll)、close
  timerfd_settime:设置timer的周期,以及起始间隔
  timerfd_gettime:获取到期时间。
//函数参数中数据结构如下:
struct timespec
{
time_t tv_sec; /* Seconds */
long tv_nsec; /* Nanoseconds */
};
struct itimerspec
{
struct timespec it_interval; /* Interval for periodic timer */
struct timespec it_value; /* Initial expiration */
};
21/212>
《2023软件测试行业现状调查报告》独家发布~

关注51Testing

联系我们

快捷面板 站点地图 联系我们 广告服务 关于我们 站长统计 发展历程

法律顾问:上海兰迪律师事务所 项棋律师
版权所有 上海博为峰软件技术股份有限公司 Copyright©51testing.com 2003-2024
投诉及意见反馈:webmaster@51testing.com; 业务联系:service@51testing.com 021-64471599-8017

沪ICP备05003035号

沪公网安备 31010102002173号