zoukankan      html  css  js  c++  java
  • 高级IO

    例:同时读取鼠标与键盘

    传统情况下,由于阻塞只能同时读取一路。

    解决方案

    1.非阻塞IO

    2.异步IO

    3.IO多路复用

    非阻塞IO

    使用O_NONBLOCK和fcntl实现非阻塞

    #include <stdio.h>
    #include <string.h>
    #include <unistd.h>
    #include <stdlib.h>
    #include <sys/types.h>
    #include <sys/stat.h>
    #include <fcntl.h>
    
    
     int main()
    {   
        int fd = -1;
        int flag = -1;
        int ret = -1;
        //把0号文件描述符(stdin)变为非阻塞
        flag = fcntl(0,F_GETFL);
        flag |= O_NONBLOCK;
        fcntl(0, F_SETFL, flag);//设置为非阻塞
         fd = open("/dev/input/mouse1", O_RDONLY|O_NONBLOCK);
        if(fd < 0)
        {
            perror("open");
            exit(-1);
        } 
        char buf[100];
        //读鼠标
        while(1)
        {
            memset(buf , 0, sizeof(buf));
            ret = read(fd , buf , 100);
            if(ret > 0)
            {
            printf("鼠标读取的内容:[%s]
    " , buf); 
            }
            memset(buf , 0, sizeof(buf));
            ret = read(0 , buf , 100);
            if(ret > 0)
            {
            printf("键盘读取的内容:[%s]
    " , buf);
            }
        }
        return 0;
    }

    异步IO

    使用select和poll实现异步IO

    特点为外部阻塞式,内部非阻塞式自动轮询多路阻塞式IO

    #include <stdio.h>
    #include <unistd.h>
    #include <string.h>
    #include <sys/types.h>
    #include <sys/stat.h>
    #include <fcntl.h>
    #include <poll.h>
    int main(void)
    {
        // 读取鼠标
        int fd = -1, ret = -1;
        char buf[200];
        struct pollfd myfds[2] = {0};
        
        fd = open("/dev/input/mouse1", O_RDONLY);
        if (fd < 0)
        {
            perror("open:");
            return -1;
        }
        
        // 初始化我们的pollfd
        myfds[0].fd = 0;            // 键盘
        myfds[0].events = POLLIN;    // 等待读操作
        
        myfds[1].fd = fd;            // 鼠标
        myfds[1].events = POLLIN;    // 等待读操作
    
        ret = poll(myfds, fd+1, 10000);
        if (ret < 0)
        {
            perror("poll: ");
            return -1;
        }
        else if (ret == 0)
        {
            printf("超时了
    ");
        }
        else
        {
            // 等到了一路IO,然后去监测到底是哪个IO到了,处理之
            if (myfds[0].events == myfds[0].revents)
            {
                // 这里处理键盘
                memset(buf, 0, sizeof(buf));
                read(0, buf, 5);
                printf("键盘读出的内容是:[%s].
    ", buf);
            }
            
            if (myfds[1].events == myfds[1].revents)
            {
                // 这里处理鼠标
                memset(buf, 0, sizeof(buf));
                read(fd, buf, 50);
                printf("鼠标读出的内容是:[%s].
    ", buf);
            }
        }
    
        return 0;
    }

    异步IO

    通过信号实现

    异步IO的工作方法是:我们当前进程注册一个异步IO事件(使用signal注册一个信号SIGIO的处理函数),然后当前进程可以正常处理自己的事情,当异步事件发生后当前进程会收到一个SIGIO信号从而执行绑定的处理函数去处理这个异步事件。
    涉及的函数:
    (1)fcntl(F_GETFL、F_SETFL、O_ASYNC、F_SETOWN)
    (2)signal或者sigaction(SIGIO)

    #include <stdio.h>
    #include <unistd.h>
    #include <string.h>
    #include <sys/types.h>
    #include <sys/stat.h>
    #include <fcntl.h>
    #include <signal.h>
    int mousefd = -1;
    // 绑定到SIGIO信号,在函数内处理异步通知事件 void func(int sig) { char buf[200] = {0}; if (sig != SIGIO) return; read(mousefd, buf, 50); printf("鼠标读出的内容是:[%s]. ", buf); } int main(void) { // 读取鼠标 char buf[200]; int flag = -1; mousefd = open("/dev/input/mouse1", O_RDONLY); if (mousefd < 0) { perror("open:"); return -1; } // 把鼠标的文件描述符设置为可以接受异步IO flag = fcntl(mousefd, F_GETFL); flag |= O_ASYNC; fcntl(mousefd, F_SETFL, flag); // 把异步IO事件的接收进程设置为当前进程 fcntl(mousefd, F_SETOWN, getpid()); // 注册当前进程的SIGIO信号捕获函数 signal(SIGIO, func); // 读键盘 while (1) { memset(buf, 0, sizeof(buf)); //printf("before 键盘 read. "); read(0, buf, 5); printf("键盘读出的内容是:[%s]. ", buf); } return 0; }

    存储映射IO

    1、mmap函数
    2、LCD显示和IPC之共享内存
    3、存储映射IO的特点
    (1)共享而不是复制,减少内存操作
    (2)处理大文件时效率高,小文件不划算

  • 相关阅读:
    app测试点
    【Android自动化打包】03. APK的数字签名
    【转】测试架构师团队的管理
    【转】用户体验质量的测试方法论-“你的风扇方案”
    【转】大数据本质与测试
    jquery 获取下拉框值与select text
    js获取下拉,单选
    jquery插件
    加密
    plsql 只能识别32位的oracle解决办法
  • 原文地址:https://www.cnblogs.com/PengfeiSong/p/6565257.html
Copyright © 2011-2022 走看看