zoukankan      html  css  js  c++  java
  • 3.6.2.阻塞式IO的困境

    本节通过实例代码运行结果,让大家看到在并发式IO访问时非阻塞IO遭遇的困境,由此引入非阻塞式IO。

    3.6.2.1、程序中读取键盘

    include <stdio.h>

    include <unistd.h>

    include <string.h>

    int main(void)
    {
    // 读取键盘
    // 键盘就是标准输入,stdin
    char buf[100];

    memset(buf, 0, sizeof(buf));
    printf("before read.
    ");
    read(0, buf, 5);
    printf("读出的内容是:[%s].
    ", buf);
    
    return 0;
    

    }

    运行过程:

    ./a.out

    before read.
    进程被阻塞住,因为此时还没有键盘输入,此时,键入一个a,

    before read.
    a
    打印一个a,然后键入bcdggggg,

    before read.
    abcdggggg
    因为linux使用行缓存技术。如果在结束,则按一个Enter就可以结束这个函数。(行缓存for直到换行符到了)。
    3.6.2.2、程序中读取鼠标
    键盘是一个标准输入设备,所以可以直接打开。但是鼠标不是标准输入设备,所以要先用open打开鼠标鼠标。

    ls /dev/input

    by-id by-path event0 event1 event2 event3 mice mouse0 mouse1

    cat /dev/input/mouse1

    如何判断哪个是我们的鼠标,只要cat /dev/input/mouse1,就会阻塞,然后移动鼠标,如果有打印出来的东西,就是当前鼠标设备。

    include <stdio.h>

    include <unistd.h>

    include <string.h>

    include <sys/types.h>

    include <sys/stat.h>

    include <fcntl.h>

    int main(void)
    {
    // 读取鼠标
    int fd = -1;
    char buf[200];

    fd = open("/dev/input/mouse1", O_RDONLY);
    if (fd < 0)
    {
        perror("open:");
        return -1;
    }
    
    memset(buf, 0, sizeof(buf));
    printf("before 鼠标 read.
    ");
    read(fd, buf, 50);
    printf("鼠标读出的内容是:[%s].
    ", buf);
    
    return 0;
    

    }

    结果分析:先前打印before 鼠标 read.阻塞住,直到鼠标移动,才打印出乱码[(�]。打印出乱码的原因是鼠标移动输入二进制,但是终端以ASCII方式解析。
    3.6.2.3、程序中同时读取键盘和鼠标(有问题没想明白)

    include <stdio.h>

    include <unistd.h>

    include <string.h>

    include <sys/types.h>

    include <sys/stat.h>

    include <fcntl.h>

    int main(void)
    {
    // 读取鼠标
    int fd = -1;
    char buf[200];

    fd = open("/dev/input/mouse1", O_RDONLY);
    if (fd < 0)
    {
        perror("open:");
        return -1;
    }
    
    memset(buf, 0, sizeof(buf));
    printf("before 鼠标 read.
    ");
    read(fd, buf, 50);
    printf("鼠标读出的内容是:[%s].
    ", buf);
    
    
    // 读键盘
    memset(buf, 0, sizeof(buf));
    printf("before 键盘 read.
    ");
    read(0, buf, 5);
    printf("键盘读出的内容是:[%s].
    ", buf);
    
    
    return 0;
    

    }
    3.6.2.4、问题分析

    总结:阻塞式IO:函数调用会被阻塞。本质是当前进程调用了函数,进入内核里面去后,因为当前进程的执行条件不满足,内核无法里面完成操作,就挂起这个进程,去执行其他进程。默认使用阻塞IO。是linux系统的常态。但是阻塞式IO有一个缺点,比如说如果要同时读取鼠标和键盘的输入(不知道鼠标动还是键盘动),就会遇见很糟糕的情况,这时我们可以用并发式IO解决,有三种方法可以实现:非阻塞IO,多路复用IO,异步IO。
    并发式IO可以解决这个问题

  • 相关阅读:
    《算法竞赛进阶指南》0x00 Hamiton路径 位运算
    HDOJ1170二叉树的遍历 经典问题
    HDOJ1527博弈论之Wythoff游戏
    HDOJ1848NIM博弈 SG函数
    CRC校验码
    Delphi DBGrid 获取焦点几行和几列
    程序进制 常用简写标识
    Delphi 转换函数 HexToBin用法 将16进制字串转成二进制
    细胞-红细胞
    细胞-白细胞-中性粒细胞
  • 原文地址:https://www.cnblogs.com/Ocean-Star/p/9245447.html
Copyright © 2011-2022 走看看