zoukankan      html  css  js  c++  java
  • 异步IO原理及相应函数

    何为异步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. ", buf);
    */


    while (1)
    {
    memset(buf, 0, sizeof(buf));
    read_ret = read(0, buf, sizeof(buf)/2);
    if (0 < read_ret)
    {
    printf("读出的键盘的数据: %s. ", 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. ", buf);
    }

  • 相关阅读:
    Screen print or copy
    <转>关于SQL Server数据库的若干注意事项
    sql server 链接到oracle库,读取对应信息
    LinkedServer链接服务器的使用
    序号生成一例
    新解:报表服务器数据库的版本格式无效,或无法读取。已找到的版本为“Unknown”,而所需的版本为“C.0.8.40”。
    GridView to Excel
    sql server临时表是否存在
    <转>SQL Server大表转为分区表实例
    <转> 人生十二个经典领悟
  • 原文地址:https://www.cnblogs.com/deng-tao/p/5994197.html
Copyright © 2011-2022 走看看