Linux信号驱动I/O 学习记录

本文介绍了Linux信号驱动I/O的工作原理和注册方法,通过实验详细分析了信号何时触发,以及不同Linux内核版本下的行为差异。实验表明,对于stdin绑定信号驱动I/O的进程,stdout的输出需要满足特定条件才能触发SIGIO,而不同内核版本对键盘输入的处理也有所不同。
摘要由CSDN通过智能技术生成

Q:什么是信号驱动I/O?
A:对于给定的I/O口(一般就是对于文件描述符)设定为信号驱动I/O,则当I/O口准备好之后(读:有数据可读;写:有空间可写),向注册它的进程发送事先约定好的信号,进程收到信号后触发signal handler进行I/O处理。

Q:Linux下信号驱动I/O的注册方法?
A:系统设定两种信号为专用信号:SIGIO和SIGURG,这两种都是非实时、不可靠信号,不能参加排队。前者是通用信号,后者则专门用于网络传输中带外数据(紧急数据)的I/O,本文不涉及。具体步骤如下:
1. 对文件描述符调用fcntl函数,设置O_NONBLOCK和O_ASYNC(只能对终端和网络的文件描述符使用)属性;
fcntl(fd, F_SETFL, old | O_NONBLOCK | O_ASYNC)
2. 对文件描述符设置SIGIO、SIGURG信号所通知的进程,一般是调用进程本身;
fcntl(fd, F_SETOWN, getpid())
3. 编写signal handler函数,并使用signal或sigaction函数注册。

这就是APUE书上所说的BSD异步I/O方法。严格的说信号驱动I/O不是异步的I/O,因为它I/O的操作本身仍然是同步的(需要进程主动去读取或写入),只是使用了signal这种异步机制通知进程什么时候该读写了,属于伪异步。

实验一:将标准输入注册为信号驱动I/O

    #include <stdio.h>
    #include <stdlib.h>
    #include <unistd.h>
    #include <errno.h>
    #include <fcntl.h>
    #include <signal.h>

    void sigio_handler(int sig)
    {
        static int cnt = 0;

        printf("receive SIGIO signal %d\n", ++cnt);
        fflush(stdin);
        fflush(stdout);
    }


    int main(int argc, char **argv)
    {
        struct sigaction sig_act;
        int fl = 0;

        //signal driven I/O setting
        fflush(stdin);
        fflush(stdout);
        fl = fcntl(STDIN_FILENO, F_GETFL, 0);
        fcntl(STDIN_FILENO, F_SETFL, fl | O_NONBLOCK | O_ASYNC );
        fcntl(STDIN_FILENO, F_SETOWN, getpid());
        sigemptyset(&sig_act.sa_mask);
        sig_act.sa_flags = 0;
        sig_act.sa_handler = sigio_handler;
        sigaction(SIGIO, &sig_act, NULL);

        printf("test start\n");
        fflush(stdin);
        fflush(stdout);

        while (1)
        {
            sleep(1);
        }

        return 0;
    }

实验结果:循环打印signal handler中的语句,如下:

test start
receive SIGIO signal 1
receive 
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值