Linux 非阻塞IO

Linux 非阻塞IO

1. fcntl()

在Linux操作系统中,fcntl() 是一个用于操作文件描述符的系统调用 。它提供了多种功能,包括控制文件描述符的属性、管理文件锁定、设置文件的非阻塞模式等。

本文只截取了用于IO模型的 fcntl() 部分内容, fcntl() 的详细内容请看--->Linux fcntl函数

在打开文件时,如果不使用fcntl()对其进行设置,这个文件就默认使用阻塞IO 。非阻塞IO和信号驱动IO都需要手动调用fcntl()才能使用。

#include <unistd.h>

#include <fcntl.h>

int fcntl(int fd, int cmd, .../* arg */)

fd: 需要进行操作的文件描述符。

cmd: 指定要进行的操作。

  1. F_GETFL 表示返回当前文件描述符的状态标志,如是否是非阻塞模式(O_NONBLOCK)。
  2. F_SETFL 表示设置文件描述符的状态标志,在可变参数(arg)中,输入要设置的状态标志,如 O_NONBLOCK(非阻塞模式)、 O_ASYNC (信号驱动模式)
c 复制代码
int flags = fcntl(fd, F_GETFL, 0);
fcntl(fd, F_SETFL, flags | O_NONBLOCK);  // 设置非阻塞模式
//或
fcntl(fd, F_SETFL, flags | O_ASYNC); //设置信号驱动模式

2. 阻塞IO

非阻塞 IO 往往需要程序员循环的方式反复尝试读写文件描述符 ,这个过程称为轮询。这对 CPU 来说是较大的浪费,一般只有特定场景下才使用。

非阻塞等待中,不论是数据未就绪还是读数据出错recv()返回值都是小于0 ,为了区分两者,c语言提供的 errno 记录了最后一次系统调用出错的错误信息。当底层数据没有就绪, errno 就会被设置为 EWOULDBLOCKEAGAIN)。

c 复制代码
//errno.h
#ifndef _ERRNO_H
#define _ERRNO_H

//.......
#define  EBADF            9  /* 文件描述符无效 */
#define  ECHILD          10  /* 子进程不存在 */
#define  EAGAIN          11  /* 资源暂时不可用,尝试重新调用 */
//.....
#endif /* _ERRNO_H */

使用非阻塞IO前,要先将文件描述符的状态标志设置为非阻塞模式:

c 复制代码
int flags = fcntl(fd, F_GETFL, 0);
fcntl(fd, F_SETFL, flags | O_NONBLOCK);  // 设置非阻塞模式
相关推荐
ltl18 小时前
实时 OS 巡礼:VxWorks、QNX、Zephyr 与 PREEMPT_RT
linux
我是谁??18 小时前
Ubuntu22.04更换清华源
linux·运维·服务器
圣殿骑士-Khtangc18 小时前
Go字符串高效拼接性能对比与底层原理分析
服务器·前端·golang
Shell运维手记19 小时前
Linux 常用基础命令学习笔记
linux·运维·笔记·学习·算法·github
朴马丁19 小时前
国际与国产PLM在精细化工赛道的布局:2026年主要厂商技术特色
大数据·运维·人工智能·流程行业plm·化工新材料
这个DBA有点耶19 小时前
数据库一体机架构演进:从硬件堆叠到软硬深度耦合
服务器·网络·数据库·硬件架构·运维开发·database·数据库架构
Elastic 中国社区官方博客20 小时前
Elasticsearch:使用 AI Agent 来创建 workflow
大数据·运维·人工智能·elasticsearch·搜索引擎·自动化·全文检索
测试运维日常笔记20 小时前
Linux系统安装配置TigerVNC服务器完整指南
linux·运维·服务器
像风一样自由202020 小时前
加强版VScode结合remote-ssh远程连接服务器开发指南
服务器·vscode·ssh
喜欢的名字被抢了21 小时前
程序出问题怎么查,以及如何让它不掉线
java·运维·数据库