linux串口编程read为什么不阻塞

不及物动词 其他 604

回复

共3条回复 我来回复
  • fiy的头像
    fiy
    Worktile&PingCode市场小伙伴
    评论

    Linux串口编程中的read函数之所以不阻塞,是因为在默认情况下,串口的输入设置为非阻塞模式。非阻塞模式是指当没有数据可读时,read函数会立即返回0,而不会等待数据到达。

    在Linux中,串口设备被视为一种特殊的文件,可以通过文件描述符进行访问。read函数用于从文件描述符中读取数据。当用于串口设备时,read函数会尝试从串口缓冲区中读取数据。

    在非阻塞模式下,read函数的行为如下:

    1. 如果串口缓冲区中有数据可读,则read函数会立即返回读取到的数据字节数。
    2. 如果串口缓冲区为空,则read函数会立即返回0,表示没有数据可读。
    3. 如果串口缓冲区中没有数据可读,并且没有设置超时机制,则read函数会阻塞,直到有数据可读为止。
    4. 如果串口缓冲区中没有数据可读,并且设置了超时机制,则read函数会阻塞,直到有数据可读或超时时间到达为止。

    为了使read函数变为阻塞模式,可以使用fcntl函数设置串口设备的属性。通过设置O_NONBLOCK标志位,可以将串口设备设置为非阻塞模式;通过清除O_NONBLOCK标志位,可以将串口设备设置为阻塞模式。

    总之,Linux串口编程中的read函数不阻塞是因为串口设备默认为非阻塞模式。如果需要read函数阻塞,可以通过设置串口设备的属性来实现。

    1年前 0条评论
  • 不及物动词的头像
    不及物动词
    这个人很懒,什么都没有留下~
    评论

    在Linux串口编程中,read函数通常是用来从串口读取数据的。根据Linux的特性,read函数在默认情况下是阻塞的,即当没有数据可读时,程序会一直等待直到有数据可读才返回。但是有时候我们希望read函数不阻塞,即使没有数据可读也能立即返回。这可以通过以下几种方式实现:

    1. 设置串口为非阻塞模式:可以使用fcntl函数来设置串口为非阻塞模式。通过将串口文件描述符的O_NONBLOCK标志位置1,即可将串口设置为非阻塞模式。这样,当没有数据可读时,read函数会立即返回一个错误码,而不会阻塞等待数据。

    2. 使用select函数进行多路复用:select函数是Linux提供的一种多路复用函数,可以同时监听多个文件描述符的可读、可写和异常事件。我们可以通过将串口文件描述符添加到select函数的监听集合中,并设置超时时间为0来实现非阻塞读取。当没有数据可读时,select函数会立即返回,此时我们可以通过read函数来读取数据。

    3. 使用poll函数进行多路复用:poll函数是Linux提供的另一种多路复用函数,与select函数类似,也可以同时监听多个文件描述符的可读、可写和异常事件。使用方式与select函数类似,将串口文件描述符添加到poll函数的监听集合中,并设置超时时间为0即可。

    4. 使用epoll函数进行多路复用:epoll函数是Linux提供的一种高性能的多路复用函数,相比于select和poll函数,epoll函数在处理大量文件描述符时性能更好。使用方式与select和poll函数类似,将串口文件描述符添加到epoll函数的监听集合中,并设置超时时间为0即可。

    5. 使用非阻塞IO函数:除了read函数,Linux还提供了其他一些非阻塞IO函数,如recv、recvfrom、recvmsg等,它们在默认情况下也是阻塞的。我们可以通过设置socket选项,将这些函数设置为非阻塞模式,从而实现非阻塞读取。

    总结起来,read函数不阻塞的原因是我们可以通过设置串口为非阻塞模式,或者使用多路复用函数进行监听,或者使用非阻塞IO函数来实现非阻塞读取。这样,在没有数据可读时,read函数会立即返回,而不会阻塞等待数据的到来。

    1年前 0条评论
  • worktile的头像
    worktile
    Worktile官方账号
    评论

    Linux串口编程中的read函数为什么不阻塞的原因主要是因为串口设备的I/O操作默认是非阻塞的。在非阻塞模式下,当没有数据可读时,read函数会立即返回,而不会等待数据的到来。

    下面我们来详细讲解一下Linux串口编程中read函数为什么不阻塞的原因。

    1. 非阻塞模式
      在Linux中,可以使用fcntl函数将串口设置为非阻塞模式。非阻塞模式下,串口设备的I/O操作不会被阻塞,即使没有数据可读,也会立即返回。

    2. 阻塞模式
      在阻塞模式下,当调用read函数时,如果没有数据可读,read函数会一直阻塞,直到有数据可读为止。这种模式下,程序会一直等待数据的到来,无法进行其他操作。

    3. 设置非阻塞模式
      在Linux中,可以使用fcntl函数设置串口为非阻塞模式。具体操作如下:

    #include <fcntl.h>
    #include <unistd.h>
    
    int set_nonblock(int fd) {
        int flags;
    
        flags = fcntl(fd, F_GETFL, 0);
        if (flags == -1) {
            perror("fcntl F_GETFL");
            return -1;
        }
    
        flags |= O_NONBLOCK;
        if (fcntl(fd, F_SETFL, flags) == -1) {
            perror("fcntl F_SETFL");
            return -1;
        }
    
        return 0;
    }
    

    上述代码中的set_nonblock函数可以将给定的文件描述符fd设置为非阻塞模式。

    1. 非阻塞模式的读取
      在非阻塞模式下,当调用read函数时,如果没有数据可读,read函数会立即返回-1,并设置errno为EAGAIN或EWOULDBLOCK。这样,我们可以通过检查errno的值来判断是否有数据可读。
    #include <stdio.h>
    #include <stdlib.h>
    #include <fcntl.h>
    #include <unistd.h>
    #include <errno.h>
    
    int main() {
        int fd;
        char buf[256];
        int ret;
    
        fd = open("/dev/ttyS0", O_RDONLY);
        if (fd == -1) {
            perror("open");
            exit(1);
        }
    
        set_nonblock(fd);
    
        while (1) {
            ret = read(fd, buf, sizeof(buf));
            if (ret == -1) {
                if (errno == EAGAIN || errno == EWOULDBLOCK) {
                    printf("No data available\n");
                    usleep(1000000);  // Sleep for 1 second
                    continue;
                } else {
                    perror("read");
                    exit(1);
                }
            } else if (ret == 0) {
                printf("End of file\n");
                break;
            } else {
                printf("Read %d bytes\n", ret);
                // Process the data
            }
        }
    
        close(fd);
    
        return 0;
    }
    

    上述代码中的while循环中,调用read函数读取数据。如果read函数返回-1,那么通过检查errno的值来判断是否有数据可读。如果没有数据可读,我们可以选择等待一段时间后再次读取,或者进行其他操作。

    总结:
    在Linux串口编程中,read函数不阻塞的原因是因为串口设备的I/O操作默认是非阻塞的。通过设置串口为非阻塞模式,我们可以在调用read函数时立即返回,而不会被阻塞。这样可以提高程序的响应速度,使得程序能够同时处理多个任务。

    1年前 0条评论
注册PingCode 在线客服
站长微信
站长微信
电话联系

400-800-1024

工作日9:30-21:00在线

分享本页
返回顶部