信号是什么?
信号是事件发送时对进程的一种通知机制 。有时也称之为软件中断 。信号与硬件中断的相似之处在于打断了程序执行的正常流程,大多情况下,无法预测信号到达的精确时间 。
一个具有合适权限的进程不仅能够向另一进程发送信号,也可以向自身发送信号 。然而,发往进程的诸多信号,通常都是源于内核 。
linux 信号可由如下条件产生:
- 对于前台进程,用户可以通过输入特殊的终端字符来给它发送信号 。比如输出 Ctrl+C 通常会给进程发送一个终端信号 。
- 系统异常 。比如浮点异常和非法访问段内存 。
- 系统状态变化 。比如 alarm 定时器到期引起的 SIGALRM 信号 。
- 运行 kill 命令或者调用 kill 函数 。
signalfd 是什么?
signalfd 是一个将信号抽象的文件描述符,将信号的异步处理转换为文件的I/O 操作 。通过文件描述符就绪的方法来通知信号的到来,当有信号发生时可以对其 read,这样可以将信号的监听放到 select、poll、epoll 等监听队列中 。
通过文件描述符就绪的方法来通知信号的到来,当有信号发生时可以对其read,这样可以将信号的监听放到 select、poll、epoll 等监听队列中 。
signalfd 的系统调用接口
#include <sys/signalfd.h>
int signalfd(int fd, const sigset_t *mask, int flags);
创建并返回一个用于所受信号的文件描述符 。
mask:信号的集合,这里主要是你想监听的信号的集合 。
【Linux signalfd 原理】flags 可以使用以下标志位进行或(or)的结果:
- SFD_NONBLOCK: 文件会被设置成 O_NONBLOCK,读操作不阻塞 。若不设置,一直阻塞直到计数器中的值大于0 。
- SFD_CLOEXEC: 在新的文件描述符上设置 close-on-exec ( FD_CLOEXEC ) 标志,简单说就是 fork 子进程时不继承 。
获取 signalfd 文件描述符后,我们来查看一下可以对其做哪些操作 。
static const struct file_operations signalfd_fops = {
#ifdef CONFIG_PROC_FS
.show_fdinfo = signalfd_show_fdinfo,
#endif
.release = signalfd_release,
.poll = signalfd_poll,
.read = signalfd_read,
.llseek = noop_llseek,
};
通过上面 signalfd 实现的调用可知,我们可以对 eventfd 进行 read、poll、close 等操作 。
下面通过一个例子来了解下 signalfd 的使用方式,具体完整代码可通过 man signalfd 获取
int main(int argc, char *argv[])
{
...
//初始化信号集
sigemptyset(&mask);
//添加信号到信号集中
sigaddset(&mask, SIGINT);
sigaddset(&mask, SIGQUIT);
//将mask所指向的信号集中所包含的信号加到当前的信号掩码中,作为新的信号屏蔽字,关闭内核的默认行为 。
sigprocmask(SIG_BLOCK, &mask, NULL)
//创建 signalfd 文件描述符
sfd = signalfd(-1, &mask, 0);
for (;;) {
//阻塞等待信号发生并读取 。根据读取的结果可以知道发生了什么信号
s = read(sfd, &fdsi, sizeof(fdsi));
if (fdsi.ssi_signo == SIGINT) {
printf("Got SIGINTn");
} else if (fdsi.ssi_signo == SIGQUIT) {
printf("Got SIGQUITn");
exit(EXIT_SUCCESS);
} else {
printf("Read unexpected signaln");
}
}
}
当没有信号时,进程阻塞在 read 调用上,当有信号发生时,结果如下:
$ ./signalfd_demo
^C # Control-C generates SIGINT
Got SIGINT
^C
Got SIGINT
^ # Control- generates SIGQUIT
Got SIGQUIT
$
每次 Control + C,进程都会捕获到一次信号,并打印具体信息 。
通过如下查看,得到 signalfd 其实也是一个匿名 fd 类型 。
[root@localhost ~]# ll /proc/48356/fd/
lrwx------ 1 root root 64 5月 23 11:54 3 ->anon_inode:[signalfd]
signalfd 源码解析
接下来我们通过分析源码的方式来探究 signalfd 的底层实现原理 。
signalfd ( signalfd4 )
推荐阅读
- Linux系统设置文件权限,多用户模式下文件权限管理
- 保温杯的保温原理;保温杯保温原理是什么?
- linux设置默认路由 linux设置默认网关
- 可控硅整流原理……可控硅可以整流吗?
- 铜电镀镀锌与镀锡的优缺点 电镀锡原理
- 防蚊手环驱蚊原理?驱蚊手环有毒吗?驱蚊手环的危害?
- 电子邮件是如何工作的 电子邮件工作原理
- 喷雾器原理及结构 喷雾器原理
- 搅拌摩擦焊接的原理 搅拌摩擦焊接
- 驱蚊手环原理 驱蚊手环怎么使用