当前位置: 首页 > news >正文

Linux下的阻塞与非阻塞模式详解

Linux下的阻塞与非阻塞模式详解

  • 一、引言
  • 二、阻塞与非阻塞模式的概念
  • 三、Linux下使用`read`和`write`函数操作标准输入输出设备
  • 四、使用预定义文件描述符
    • 1. 直接使用预定义文件描述符
    • 2. 设置非阻塞模式
  • 五、设置阻塞属性
    • 1. 通过`open`函数设置阻塞属性
    • 2. 通过`fcntl`函数设置阻塞属性
  • 六、Linux上具有阻塞属性的文件
  • 七、总结

在Linux系统中,阻塞与非阻塞模式是处理I/O操作时的重要概念,尤其在串口通信和终端操作中。本文将详细探讨阻塞与非阻塞模式的概念、Linux下使用 readwrite函数操作标准输入输出设备的方法、如何通过 open设置阻塞属性,以及在非阻塞模式下使用 readwrite操作终端等内容。


一、引言

在现代计算机系统中,I/O操作是程序运行中不可或缺的一部分。无论是从标准输入读取用户输入,还是通过网络套接字传输数据,I/O操作的效率和响应时间对程序的整体性能有着重要影响。阻塞与非阻塞模式作为I/O操作的两种基本处理方式,直接影响着程序的运行效率和用户体验。

本文将深入探讨Linux系统中阻塞与非阻塞模式的概念、实现方法以及实际应用,帮助开发者在实际开发中做出合理的选择,以提升程序的性能和响应能力。


二、阻塞与非阻塞模式的概念

阻塞与非阻塞模式主要用于描述I/O操作的处理方式:

  1. 阻塞模式(Blocking Mode)
    在阻塞模式下,read函数会一直等待,直到有数据到达或满足特定条件(如超时)才会返回。如果没有任何数据到达,read会阻塞程序,直到有数据为止【1†source】【4†source】。

  2. 非阻塞模式(Non-Blocking Mode)
    在非阻塞模式下,read函数不会等待数据到达,而是立即返回。如果此时没有数据,read会返回0字节,并继续执行后续代码【4†source】【5†source】。

这种模式的选择对程序的性能和响应时间有重要影响。例如,在实时系统中,非阻塞模式可以避免程序因等待I/O操作而卡死。


三、Linux下使用readwrite函数操作标准输入输出设备

在Linux中,标准输入输出设备(如终端/dev/tty)默认是阻塞模式。readwrite函数用于从终端读取或写入数据:

在阻塞模式下,read函数会一直等待,直到有数据到达才会返回。write函数则通常不会阻塞,因为它只是将数据写入缓冲区。但在某些特殊情况下(如网络套接字),write可能会阻塞,直到数据被传输完毕。

示例代码:阻塞模式下的readwrite

#include <unistd.h>
#include <stdio.h>int main() {char buffer[100];ssize_t bytes_read;printf("请输入一些文字(按回车键确认):\n");// 读取输入数据,阻塞模式下会等待用户输入bytes_read = read(STDIN_FILENO, buffer, sizeof(buffer));if (bytes_read > 0) {// 写入输出数据,将读取到的内容写回终端write(STDOUT_FILENO, "你输入的内容是:", 16);write(STDOUT_FILENO, buffer, bytes_read);}return 0;
}

四、使用预定义文件描述符

在Linux系统中,文件描述符0、1和2分别对应标准输入(stdin)、标准输出(stdout)和标准错误(stderr)。这些文件描述符在程序启动时就已经打开,无需调用open函数【5†source】【6†source】【9†source】。

1. 直接使用预定义文件描述符

无需调用open函数,可以直接使用预定义的文件描述符进行读写操作。例如:

#include <unistd.h>
#include <stdio.h>int main() {char buffer[100];ssize_t bytes_read;// 读取标准输入printf("请输入一些文字:");bytes_read = read(STDIN_FILENO, buffer, sizeof(buffer));if (bytes_read > 0) {// 写入标准输出write(STDOUT_FILENO, "你输入的内容是:", 16);write(STDOUT_FILENO, buffer, bytes_read);}return 0;
}

2. 设置非阻塞模式

如果需要,可以通过fcntl函数将文件描述符设置为非阻塞模式:

#include <fcntl.h>int main() {char buffer[100];ssize_t bytes_read;// 设置标准输入为非阻塞模式int flags = fcntl(STDIN_FILENO, F_GETFL);flags |= O_NONBLOCK;fcntl(STDIN_FILENO, F_SETFL, flags);while (1) {bytes_read = read(STDIN_FILENO, buffer, sizeof(buffer));if (bytes_read > 0) {write(STDOUT_FILENO, "你输入的内容是:", 16);write(STDOUT_FILENO, buffer, bytes_read);}sleep(1); // 模拟其他任务}return 0;
}

五、设置阻塞属性

1. 通过open函数设置阻塞属性

在Linux中,可以通过open函数打开设备文件时设置阻塞属性。例如:

int fd = open("/dev/tty", O_RDWR | O_NONBLOCK);

2. 通过fcntl函数设置阻塞属性

如果设备文件已经打开,可以使用fcntl函数动态修改阻塞属性:

int flags = fcntl(fd, F_GETFL);
flags |= O_NONBLOCK;
fcntl(fd, F_SETFL, flags);

六、Linux上具有阻塞属性的文件

在Linux系统中,以下文件通常具有阻塞属性:

  1. 终端设备文件
    /dev/tty/dev/pts/0等,这些文件默认以阻塞模式打开【5†source】【6†source】。

  2. 串口设备文件
    /dev/ttyUSB0(USB转串口设备),这些文件在默认情况下也是阻塞模式【8†source】。

  3. 网络套接字
    网络套接字默认是阻塞模式,但在某些情况下(如服务器程序)需要设置为非阻塞模式以提高性能【4†source】。


七、总结

阻塞与非阻塞模式是Linux系统中处理I/O操作的重要概念。阻塞模式适用于需要等待数据到达的场景,而非阻塞模式适用于需要同时处理多个任务的场景。通过合理设置阻塞属性,可以显著提高程序的性能和响应能力。

在实际开发中,可以根据具体需求选择合适的模式。例如,在串口通信中,非阻塞模式可以避免程序因等待数据而卡死;而在标准输入输出中,阻塞模式可以确保程序按预期等待用户输入。

希望本文对您理解Linux下的阻塞与非阻塞模式有所帮助!

http://www.dtcms.com/a/477351.html

相关文章:

  • 计算机网络基础篇——物理层
  • 【开题答辩全过程】以 标本销售管理系统为例,包含答辩的问题和答案
  • 中国 TOB 信息安全市场增长洞察报告(2020-2024):细分领域表现与战略机遇
  • SSM(Spring+SpringMVC+Mybatis)整合
  • 网站排名推广汕头发展
  • 【Linux】初始线程
  • WSL SSH 服务器一站式配置教程
  • 网站建设企业资质等级做游戏模板下载网站有哪些
  • C++ bit级别的复制
  • 《算法闯关指南:优选算法--二分查找》--17.二分查找(附二分查找算法简介),18. 在排序数组中查找元素的第一个和最后一个位置
  • 浏览器原理之详解渲染进程!
  • JSON衍生:JSON5、JSONL、JSONC、NDJSON、BSON、JSONB、JSONP、HOCON
  • 【Java Xml】dom4j写入XML
  • F024 vue+flask电影知识图谱推荐系统vue+neo4j +python实现
  • C++设计模式_结构型模式_外观模式Facade
  • 第 7 篇:交互的乐趣 - 响应用户输入
  • 解决Chrome 140以上版本“此扩展程序不再受支持,因此已停用”问题 axure插件安装问题
  • 如何在火语言中指定启动 Chrome 特定用户配置文件
  • 轻松测试二维码生成与识别:使用Python的qrcode、opencv和pyzbar库
  • 清河做网站报价大背景 网站
  • 迅捷视频转换器 v18.4.23 图文安装教程|支持MP4、AVI、MKV等多格式视频转换
  • 【AI论文】通过渐进式一致性蒸馏实现高效的多模态大语言模型
  • 怎么查看网站开发人网站建设流程及相应技术
  • kubecm切换k8s集群工具
  • Azure多项目管理全攻略:从资源部署到成本分析与优化
  • 怎么做游戏试玩网站城乡建设部网站 挂证
  • 历劫波,明真我——Debug Commune
  • Vue.js 模板语法
  • Spark RDD 宽窄依赖:从 DAG 到 Shuffle 的性能之道
  • scRNA-seq还是snRNA-seq,如何选择