信号驱动io

本文介绍了如何使用信号驱动式I/O在非阻塞套接口中实现异步通知,以及在TCP套接字中的应用局限性。它强调了SIGIO信号在特定场景下的优势和在处理TCP连接中的复杂性。

1. 创建套接口并设置其为非阻塞模式。

2使用sigaction函数或signal函数设置相应的信号处理程序

3.将套接口与信号关联起来,使用fcntl函数设置F_SETOWN标志和FASYNC标志。F_SETOWN标志将所有发送给进程的信号都转发给指定的进程ID,而FASYNC标志则允许套接口被设置为异步通知方式。

4. 等待信号触发。当套接口上有可用数据时,内核将发送SIGIO信号给进程,此时信号处理程序将被调用,并且可以执行相应的操作。

当数据准备好时,进程会收到一个SIGIO信号

优势在于等待数据报到达(第一阶段)期间,进程可以继续执行,不被阻塞。免去了select的阻塞与轮询,当有活跃套接字时,再由注册的handler 处理, 无需进程主动去check活跃的socket,把检查工作交给内核,进程只需要确定合适处理拷贝即可

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

#define BUF_SIZE 1024

static int fd;
static char buffer[BUF_SIZE];

void sigio_handler(int signum)
{
    int len = read(fd, buffer, BUF_SIZE);
    if (len > 0) {
        printf("Received data: %s\n", buffer);
    }
}

int main()
{
    fd = open("/dev/input/mouse0", O_RDONLY | O_NONBLOCK);
    if (fd < 0) {
        perror("open");
        exit(1);
    }

    fcntl(fd, F_SETOWN, getpid());
    fcntl(fd, F_SETFL, fcntl(fd, F_GETFL) | FASYNC);

    signal(SIGIO, sigio_handler);

    while (1) {
        sleep(1);
    }

    close(fd);

    return 0;
}

O_ASYNC标志是POSIX规范中比较新的内容,支持该标志的系统不多,后面我们会改动ioctl的FIOASYNC请求代为开启信号驱动式I/O

在TCP中的使用

信号驱动式I/O对于TCP套接字产生的作用不大。因为该信号在TCP套接字中产生的过于频繁。

以下条件均会导致对一个TCP套接字产生SIGIO信号:

监听套接字上某个连接请求已经完成;
某个断连请求已经发起;
某个断连请求已经完成;
某个连接之半已经关闭;
数据到达套接字;
数据已经从套接字发送走;
发生某个异步错误。
这么多条件都会触发SIGIO信号,导致应用进程对该信号一头雾水,没法确定套接字具体发生了什么事情。


 不过可以对TCP监听套接字可以使用SIGIO,因为对于监听套接字,产生SIGIO信号的唯一条件是某个新连接完成了。这样就可以在SIGIO信号处理函数中获取新连接了

评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值