Blocking, non-blocking IO

Blocking and non-blocking are for files, not for read, write, etc. attributes.

blocking IO

The application calls the IO function, causing the application to block, waiting for the data to be ready. If the data is not ready, it has been waiting for the data to be ready, copied from the kernel to the user space, and the IO function returns a success indication.

write picture description here

Reading a regular file will not block, no matter how many bytes are read, read will return within a limited time. Generally, network and terminal device IO are blocking I/O.

If the data input from the terminal does not have a newline, calling read to read the terminal device will block. If no data packets are received on the network, calling read to read from the network will block. It is uncertain how long it will block. Blocks there until no data arrives.

Sample code:

#include <errno.h>
#include <stdio.h>
#include <unistd.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>

int main()
{
    char buf[1024] = {0};
    printf("读数据前:\n");
    read(0, buf, sizeof(buf));  //默认是阻塞的,从标准输入读取内容
    printf("读取数据后:buf = %s\n", buf);

    return 0;
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17

operation result: 
write picture description here

non-blocking IO

When we set a file to be non-blocking, we tell the kernel not to put the process to sleep, but to return an error (EAGAIN) when the requested I/O operation cannot be completed.

In this way, our I/O operation function will continuously test whether the data is ready, and if not, continue to test until the data is ready. In the process of continuous testing, it will take up a lot of CPU time, and all general Web servers do not use this I/O model. 
write picture description here

Sample code:

#include <errno.h>
#include <stdio.h>
#include <unistd.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>

int main()
{
    int fd;
    //以非阻塞方式打开当前终端
    fd = open("/dev/tty", O_RDONLY|O_NONBLOCK); 
    if(fd < 0)
    {
        perror("open\n");
        return -1;
    }

    char buf[1024];
    while(1)
    {   
        int n = read(fd, buf, sizeof(buf));
        printf("n = %d, errno = %d, EAGAIN = %d\n", n, errno, EAGAIN);
        sleep(1); //延时

        if(n <= 0)
        {
            //如果为非阻塞,但是没有数据可读,此时全局变量 errno 被设置为 EAGAIN
            if(errno == EAGAIN)
            {
                printf("没有数据可读\n");
            }
            else
            {
                perror("read");
                break;
            }
        }
        else
        {//有数据
            printf("buf = %s\n", buf);
            break;
        }
    }

    return 0;
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40
  • 41
  • 42
  • 43
  • 44
  • 45
  • 46
  • 47
  • 48

operation result: 

write picture description here

Please indicate the source for reprint: https://blog.csdn.net/tennysonsky/article/details/78534432

Guess you like

Origin http://43.154.161.224:23101/article/api/json?id=324871673&siteId=291194637