我是靠谱客的博主 无心盼望,最近开发中收集的这篇文章主要介绍信号驱动I/O详解1、Linux中的信号2、信号驱动I/O,觉得挺不错的,现在分享给大家,希望可以做个参考。

概述

1、Linux中的信号

1.1、查看信号

[centos6-jk128:latest ~]$ kill -l
1) SIGHUP
2) SIGINT
3) SIGQUIT
4) SIGILL
5) SIGTRAP
6) SIGABRT
7) SIGBUS
8) SIGFPE
9) SIGKILL
10) SIGUSR1
11) SIGSEGV
12) SIGUSR2
13) SIGPIPE
14) SIGALRM
15) SIGTERM
16) SIGSTKFLT
17) SIGCHLD
18) SIGCONT
19) SIGSTOP
20) SIGTSTP
21) SIGTTIN
22) SIGTTOU
23) SIGURG
24) SIGXCPU
25) SIGXFSZ
26) SIGVTALRM
27) SIGPROF
28) SIGWINCH
29) SIGIO
30) SIGPWR
31) SIGSYS
34) SIGRTMIN
35) SIGRTMIN+1
36) SIGRTMIN+2
37) SIGRTMIN+3
38) SIGRTMIN+4
39) SIGRTMIN+5
40) SIGRTMIN+6
41) SIGRTMIN+7
42) SIGRTMIN+8
43) SIGRTMIN+9
44) SIGRTMIN+10 45) SIGRTMIN+11 46) SIGRTMIN+12 47) SIGRTMIN+13
48) SIGRTMIN+14 49) SIGRTMIN+15 50) SIGRTMAX-14 51) SIGRTMAX-13 52) SIGRTMAX-12
53) SIGRTMAX-11 54) SIGRTMAX-10 55) SIGRTMAX-9
56) SIGRTMAX-8
57) SIGRTMAX-7
58) SIGRTMAX-6
59) SIGRTMAX-5
60) SIGRTMAX-4
61) SIGRTMAX-3
62) SIGRTMAX-2
63) SIGRTMAX-1
64) SIGRTMAX

(1)使用"kill -l"查看linux中的全部信号,信号又分为可靠信号和不可靠信号,每个信号更详细的介绍自行查询;
(2)信号驱动I/O中使用的SIGIO信号;

1.2、信号处理方式

(1)忽略:接收到信号后不做任何反应;
(2)捕获:用自定义的信号处理函数来执行相应信号;不是所有信号都可以捕获的,关闭进程的信号就不能捕获;
(3)默认:按系统默认的信号处理方式响应信号,不去显示的指定信号处理方式,就是按默认的方式;

1.3、信号注册

	sighandler_t signal(int signum, sighandler_t handler)

(1)signum:要捕获的信号;
(2)handler:当进程接收到信号时绑定的处理函数;

2、信号驱动I/O

2.1、信号驱动I/O的原理

(1)应用层打开文件并设置好文件的相关标志位;
(2)绑定SIGIO信号处理函数,在信号处理函数中读/写文件;
(3)当驱动中有可读数据时,向相应进程发送SIGIO信号;
(4)进程接收到SIGIO信号后,运行绑定的信号处理函数;
总结:应用层打开文件并绑定信号处理函数,进程并不会阻塞,只有在接收到SIGIO信号时才去执行信号处理函数,属于异步通知;

2.2、应用层实现信号驱动I/O

void func(int signo)
{
读文件的操作;
}
fd = open("/dev/hellodev",O_RDWR);
fcntl(fd,F_SETOWN,getpid());
flage=fcntl(fd,F_GETFL);
fcntl(fd,F_SETFL,flage|FASYNC);
signal(SIGIO,func);

(1)应用层打开文件得到文件描述符,设置文件的属主进程,属主进程的进程ID号被保存代struct file filep->fowner中,将来内核才知道应该给
哪个进程发SIGIO信号;
(2)设置文件的FASYNC标志,通过fcntl的F_SETFL命令实现,也就是调用文件的file_operations结构体的fasync方法;
(3)绑定进程的SIGIO信号的响应函数;
总结:执行完上面的步骤,当文件在新数据到达时向进程发送一个SIGIO信号,进程就去读文件;

2.3、驱动层使用信号驱动I/O

//这是fasync_helper()函数和kill_fasync()函数需要用到的,照着写就行
struct fasync_struct *hello_fasync;
static struct file_operations hello_ops =
{
.open = hello_open,
.release = hello_release,
.read = hello_read,
.write = hello_write,
.fasync = hello_fasync_func,
};
int hello_fasync_func (int fd, struct file *filep, int on)
{
printk("hello_fasync_func()n");
return fasync_helper(fd, filep, on, &hello_fasync);
}
static ssize_t hello_write (struct file *filep, const char __user *buf, size_t size, loff_t *pos)
{
······
kill_fasync(&hello_fasync, SIGIO, POLLIN); //给注册的进程发送SIGIO信号
······
return size;
}

(1)F_SETOWN被调用时对file->f_owner赋值,此外什么也不做;
(2)在执行F_SETFL启动FASYNC时,调用驱动程序的fasync方法,上面的代码中就是执行hello_fasync_func()函数;
(3)当数据到达时,也就是有其他的进程调用驱动的write函数写数据时,向注册为异步通知的进程发送SIGIO信号;
(4)hello_fasync:这是fasync_helper()函数和kill_fasync()函数需要用到的信息,照着格式写就行;
(5)POLLIN:表示文件数据可读;

最后

以上就是无心盼望为你收集整理的信号驱动I/O详解1、Linux中的信号2、信号驱动I/O的全部内容,希望文章能够帮你解决信号驱动I/O详解1、Linux中的信号2、信号驱动I/O所遇到的程序开发问题。

如果觉得靠谱客网站的内容还不错,欢迎将靠谱客网站推荐给程序员好友。

本图文内容来源于网友提供,作为学习参考使用,或来自网络收集整理,版权属于原作者所有。
点赞(47)

评论列表共有 0 条评论

立即
投稿
返回
顶部