何为异步IO?
(1)几乎可以认为:异步IO就是操作系统用软件实现的一套中断响应系统。
(2)异步IO的工作方法是:我们当前进程注册一个异步IO事件(使用signal注册一个信号
SIGIO的处理函数),然后当前进程可以正常处理自己的事情,当异步事件发生后当前进
程会收到一个SIGIO信号从而执行绑定的处理函数去处理这个异步事件。其实所有的信号
都是软件实现的一种中断机制,所以异步IO其实就是利用了信号这种软件中断机制来工作
的,工作流程如下:
1):设置设备文件fd具有接收IO的功能
2):设置异步IO事件的接收进程
3):注册信号处理函数(也就是绑定)
涉及的函数:
(1)fcntl(F_GETFL、F_SETFL、O_ASYNC、F_SETOWN)
F_GETFL:获取设备文件fd的操作属性
F_SETFL:设置设备文件fd的操作属性
O_ASYNC:用来设置fd具有可接收异步IO信号的功能
F_SETOWN:设置异步IO事件的接收进程
(2)signal或者sigaction(SIGIO)
示例代码:
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <unistd.h>
#include <signal.h>
#define FILE "/dev/input/mouse0"
static int fd = -1;
static inline void funcIO(int sig);
int main(void)
{
int flag = -1;
int sig_ret = -1;
int read_ret = -1;
char buf[100] = {0};
struct sigaction sig = {
.sa_handler = funcIO,
};
//打开设备文件
fd = open(FILE, O_RDONLY);
if (-1 == fd)
{
perror("open error");
exit(-1);
}
//把鼠标的fd设置为可接收异步IO信号
flag = fcntl(fd, F_GETFL); //读出fd的属性
flag |= O_ASYNC; //添加O_ASYNC属性,使之具有可接收异步IO信号
fcntl(fd, F_SETFL, flag); //设置属性
//设置当前进程为异步IO事件的接收进程
fcntl(fd, F_SETOWN, getpid());
//绑定异步IO事件处理函数
sig_ret = sigaction(SIGIO, &sig, NULL); //表示不获取旧的处理函数
if (-1 == sig_ret)
{
perror("sigaction error");
exit(-1);
}
/*
//键盘以阻塞的方式
read(0, buf, sizeof(buf)/2);
printf("读出的键盘的数据: %s.\n", buf);
*/
while (1)
{
memset(buf, 0, sizeof(buf));
read_ret = read(0, buf, sizeof(buf)/2);
if (0 < read_ret)
{
printf("读出的键盘的数据: %s.\n", buf);
}
}
//关闭文件描述符
close(fd);
return 0;
}
static inline void funcIO(int sig)
{
char buf[100] = {0};
if (SIGIO != sig)
return;
read(fd, buf, sizeof(buf)/2);
printf("读出的鼠标的数据: %s.\n", buf);
}