1.异步IO
异步通知:异步通知是一种非阻塞的通知机制,发送方发送通知后不需要等待接收方的响应或确认。通知发送后,发送方可以继续执行其他操作,而无需等待接收方处理通知。
1. 通过信号方式,当内核检测到设备数据后,会主动给应用发送信号SIGIO。
2. 应用程序收到信号后做异步处理即可。
3. 应用程序需要把自己的进程号告诉内核,并打开异步通知机制。
2.函数接口
步骤:
(1)将文件描述符和进程号交给内核驱动
(2)打开异步通信方式,(修改文件描述符属性,步骤可见非阻塞io)
获取文件描述符属性
修改异步属性
设置异步属性
(3)内核检测到文件描述符有事件发生,给进程发送sigio信号,
(4)进程捕捉signo信号进行预期处理。
//1.设置将文件描述符和进程号提交给内核驱动
//一旦fd有事件响应, 则内核驱动会给进程号发送一个SIGIO的信号
fcntl(fd,F_SETOWN,getpid());
//2.设置异步通知
int flags;
flags = fcntl(fd, F_GETFL); //获取原属性
flags |= O_ASYNC; //给flags设置异步 O_ASUNC 通知
fcntl(fd, F_SETFL, flags); //修改的属性设置进去,此时fd属于异步
//3.signal捕捉SIGIO信号 --- SIGIO:内核通知会进程有新的IO信号可用
//一旦内核给进程发送sigio信号,则执行handler
signal(SIGIO,handler);
3.异步IO练习
异步io实现,当终端输入内容时,进程获取内容并从终端输出,当没有内容输入时,进程循环输出hello。
#include <fcntl.h>
#include <unistd.h>
#include <stdio.h>
#include <signal.h>
int fd;
void handler(int sig)
{
printf("---------------\n");
char buf[32] = "";
read(fd, buf, sizeof(buf));
printf("mouse: %s\n", buf);
}
int main(int argc, char const *argv[])
{
fd = open("/dev/input/mouse0", O_RDONLY);
if (fd < 0)
{
perror("open error");
return -1;
}
// 1. 将进程号与以及文件描述符交给内核
fcntl(fd, __F_SETOWN, getpid());
// 2.打开异步通信方式
// 获取属性
int st = fcntl(fd, F_GETFL);
// 修改异步属性
st = st | O_ASYNC;
// 设置属性
fcntl(fd, F_SETFL, st);
// 3.内核检测到文件描述符有事件发生,会给进程发送SIGIO信号
// 进程捕捉SIGNO信号进行处理
signal(SIGIO, handler);
while (1)
{
printf("hello\n");
sleep(1);
}
return 0;
}