fcntl()函数的概念和使用案例 c语言
在 Linux 系统编程中,fcntl()
函数(File Control)是用于操作文件描述符的核心函数,可控制文件或套接字的底层属性。它支持多种操作,包括设置非阻塞模式、获取/设置文件状态标志、管理文件锁等。以下是详细概念和使用案例:
核心概念
1. 函数原型
#include <unistd.h>
#include <fcntl.h>int fcntl(int fd, int cmd, ... /* arg */ );
- 参数:
fd
:要操作的文件描述符(文件、管道、套接字等)。cmd
:控制命令(如F_GETFL
、F_SETFL
、F_SETLK
等)。arg
:可选参数,具体类型取决于cmd
。
- 返回值:
- 成功:根据
cmd
不同返回不同值(如F_GETFL
返回当前标志位)。 - 失败:返回
-1
,错误码通过errno
获取。
- 成功:根据
2. 常用命令(cmd
参数)
命令 | 作用 |
---|---|
F_GETFL | 获取文件状态标志(如 O_RDONLY 、O_NONBLOCK )。 |
F_SETFL | 设置文件状态标志(只能修改部分标志,如 O_NONBLOCK 、O_APPEND )。 |
F_GETFD | 获取文件描述符标志(如 FD_CLOEXEC )。 |
F_SETFD | 设置文件描述符标志。 |
F_SETLK | 设置文件锁(非阻塞)。 |
F_SETLKW | 设置文件锁(阻塞)。 |
F_GETLK | 检查锁是否可设置。 |
使用案例
1. 设置文件描述符为非阻塞模式
常用于套接字或管道,避免 read
、accept
等调用阻塞程序。
#include <fcntl.h>
#include <unistd.h>int set_nonblocking(int fd) {int flags = fcntl(fd, F_GETFL, 0); // 获取当前标志if (flags == -1) {return -1; // 错误处理}flags |= O_NONBLOCK; // 添加非阻塞标志if (fcntl(fd, F_SETFL, flags) == -1) {return -1; // 错误处理}return 0;
}// 示例:设置套接字为非阻塞
int sockfd = socket(AF_INET, SOCK_STREAM, 0);
set_nonblocking(sockfd);
2. 设置文件追加模式
确保每次写入文件时数据追加到末尾。
int fd = open("log.txt", O_WRONLY | O_CREAT, 0644);
int flags = fcntl(fd, F_GETFL, 0);
flags |= O_APPEND;
fcntl(fd, F_SETFL, flags);
3. 文件锁(防止多进程/多线程竞争)
通过锁机制协调多个进程对同一文件的访问。
#include <fcntl.h>
#include <stdio.h>int lock_file(int fd) {struct flock fl;fl.l_type = F_WRLCK; // 排他锁(写锁)fl.l_whence = SEEK_SET; // 从文件头开始fl.l_start = 0; // 锁定区域起始偏移fl.l_len = 0; // 锁定到文件末尾fl.l_pid = getpid(); // 当前进程ID// 非阻塞方式尝试加锁if (fcntl(fd, F_SETLK, &fl) == -1) {perror("fcntl: lock failed");return -1;}return 0;
}int unlock_file(int fd) {struct flock fl;fl.l_type = F_UNLCK; // 解锁fl.l_whence = SEEK_SET;fl.l_start = 0;fl.l_len = 0;fl.l_pid = getpid();if (fcntl(fd, F_SETLK, &fl) == -1) {perror("fcntl: unlock failed");return -1;}return 0;
}// 使用示例
int main() {int fd = open("data.txt", O_RDWR | O_CREAT, 0644);if (fd == -1) {perror("open failed");return 1;}if (lock_file(fd) == 0) {printf("Lock acquired!\n");// 写入数据...unlock_file(fd);}close(fd);return 0;
}
关键注意事项
-
非阻塞模式
- 对套接字设置
O_NONBLOCK
后,accept
、read
、write
等操作会立即返回,需检查errno
是否为EAGAIN
或EWOULDBLOCK
。 - 示例检查非阻塞读:
char buf[1024]; ssize_t n = read(fd, buf, sizeof(buf)); if (n == -1) {if (errno == EAGAIN || errno == EWOULDBLOCK) {// 无数据可读,稍后重试} else {perror("read error");} }
- 对套接字设置
-
文件锁
- 锁类型:
F_RDLCK
:共享读锁(允许多个进程同时读)。F_WRLCK
:排他写锁(独占文件)。F_UNLCK
:释放锁。
- 锁继承:文件锁不会被子进程继承。
- 锁范围:
l_start
和l_len
定义锁定区域,l_len = 0
表示到文件末尾。
- 锁类型:
-
原子性操作
fcntl
的锁操作是原子性的,适合多进程同步。
-
错误处理
- 检查
fcntl
返回值,结合errno
处理错误(如EACCES
、EBADF
)。
- 检查
扩展案例:检查文件锁状态
void check_lock(int fd) {struct flock fl;fl.l_type = F_WRLCK; // 检查写锁fl.l_whence = SEEK_SET;fl.l_start = 0;fl.l_len = 0;fl.l_pid = getpid();if (fcntl(fd, F_GETLK, &fl) == -1) {perror("fcntl: F_GETLK failed");return;}if (fl.l_type == F_UNLCK) {printf("No lock on the file.\n");} else {printf("File is locked by process %d\n", fl.l_pid);}
}
总结
fcntl
的核心用途:- 修改文件描述符属性(如非阻塞模式)。
- 管理文件锁(协调多进程/线程访问)。
- 获取或设置文件状态标志。
- 典型场景:
- 网络编程中设置非阻塞套接字。
- 多进程日志文件的并发写入控制。
- 确保文件操作的原子性。
相关文章:
fcntl()函数的概念和使用案例 c语言
在 Linux 系统编程中,fcntl() 函数(File Control)是用于操作文件描述符的核心函数,可控制文件或套接字的底层属性。它支持多种操作,包括设置非阻塞模式、获取/设置文件状态标志、管理文件锁等。以下是详细概念和使用案…...

Linux红帽:RHCSA认证知识讲解(一)RedHat背景与环境配置
Linux红帽:RHCSA认证知识讲解(一)RedHat背景与环境配置 前言一、RedHat公司背景二、RedHat环境安装步骤三、windows使用远程工具连接环境并上传文件到redhat方法: 前言 在接下来的博客中,我们从基础开始将介绍红帽Linu…...

Windows11安装GPU版本Pytorch2.6教程
1: 准备工作 针对已经安装好的Windows11系统,先检查Nvidia驱动和使用的CUDA版本情况。先打开Windows PowerShell,通过nvidia-smi命令查看GPU的情况,结果如下图1所示,从结果中可知使用的CUDA版本为12.8。 图1:检测安装…...
网络传输的七层协议
网络传输的七层协议是 OSI模型(开放系统互联模型) 中的七个层次,每一层都负责不同的网络功能。具体如下: 物理层(Physical Layer) 负责在物理媒介上传输比特流,即将数据以电信号、光信号等形式在…...
【蓝桥杯集训·每日一题2025】 AcWing 6134. 哞叫时间II python
6134. 哞叫时间II Week 1 2月20日 农夫约翰正在试图向埃尔茜描述他最喜欢的 USACO 竞赛,但她很难理解为什么他这么喜欢它。 他说「竞赛中我最喜欢的部分是贝茜说『现在是哞哞时间』并在整个竞赛中一直哞哞叫」。 埃尔茜仍然不理解,所以农夫约翰将竞赛…...
Spring Boot数据访问(JDBC)全解析:从基础配置到高级调优
文章目录 引言一、Spring Boot JDBC核心架构1.1 核心组件关系图1.2 自动配置逻辑 二、基础配置实践2.1 数据源配置2.2 多数据源配置 三、JdbcTemplate深度使用3.1 基础CRUD操作3.2 批处理优化 四、事务管理4.1 声明式事务4.2 事务传播机制 五、异常处理5.1 Spring异常体系5.2 自…...
三数之和:经典问题的多种优化策略
三数之和:经典问题的多种优化策略 大家好,我是Echo_Wish。今天我们来聊一个经典的算法问题——三数之和(3Sum)。它是许多面试和算法竞赛中常见的问题之一,也常常考察我们对算法优化的理解和技巧。我们不仅要解决问题&…...
信息学奥赛一本通 1520:【 例 1】分离的路径 | 洛谷 P2860 [USACO06JAN]Redundant Paths G
【题目链接】 ybt 1520:【 例 1】分离的路径 洛谷 P2860 [USACO06JAN]Redundant Paths G 【题目考点】 1. 图论:割边(桥) 边双连通分量 【解题思路】 每个草场是一个顶点,草场之间的双向路是无向边,该…...

架构师面试(六):熔断和降级
问题 在千万日活的电商系统中,商品列表页服务通过 RPC 调用广告服务;经过统计发现,在最近10秒的时间里,商品列表页服务在对广告服务的调用中有 98% 的调用是超时的; 针对这个场景,下面哪几项的说法是正确的…...

使用 DeepSeek 生成流程图、甘特图与思维导图:结合 Typora 和 XMind 的高效工作流
在现代工作与学习中,可视化工具如流程图、甘特图和思维导图能够极大地提升信息整理与表达的效率。本文将详细介绍如何使用 DeepSeek 生成 Mermaid 文本,结合 Typora 快速生成流程图和甘特图,并通过 Markdown 格式生成思维导图,最终…...
粘贴到Word里的图片显示不全
粘贴到Word里的图片显示不全,可从Word设置、图片本身、软件与系统等方面着手解决,具体方法如下: Word软件设置 经实践发现,图片在word行距的行距出现问题,可以按照如下调整行距进行处理 修改段落行距: 选…...

【C语言】结构体内存对齐问题
1.结构体内存对齐 我们已经基本掌握了结构体的使用了。那我们现在必须得知道结构体在内存中是如何存储的?内存是如何分配的?所以我们得知道如何计算结构体的大小?这就引出了我们今天所要探讨的内容:结构体内存对齐。 1.1 对齐规…...

【蓝桥杯单片机】第十三届省赛第二场
一、真题 二、模块构建 1.编写初始化函数(init.c) void Cls_Peripheral(void); 关闭led led对应的锁存器由Y4C控制关闭蜂鸣器和继电器 2.编写LED函数(led.c) void Led_Disp(unsigned char ucLed); 将ucLed取反的值赋给P0 开启锁存器 关闭锁存…...
类与对象(5)
上一章是类与对象(4)-CSDN博客 深入了构造函数和静态成员,大概讲解了类型转换 最后一章最后一章 友元 在 C 中,友元提供了一种突破类的访问控制(封装)的方式。通过友元,外部的函数或类可以访…...
AI知识架构之数据采集
数据采集 数据格式: 结构化数据:以固定格式和结构存储,如数据库中的表以及 Excel 表格,易于查询和分析。半结构化数据:有一定结构但不如结构化数据严格,XML 常用于数据交换,JSON 在 Web 应用中广泛用于数据传输和存储。非结构化数据:无预定义结构,文本、图像、音频和视…...

细说STM32F407单片机2个ADC使用DMA同步采集各自的1个输入通道的方法
目录 一、示例说明 二、工程配置 1、RCC、DEBUG、CodeGenerator 2、USART6 3、TIM3 (1)Mode (2)参数设置 (3) TRGO (4)ADC1_IN0 1)ADCs_Common_Settings 2&a…...
C# 将非托管Dll嵌入exe中(一种实现方法)
一、环境准备 电脑系统:Windows 10 专业版 20H2 IDE:Microsoft Visual Studio Professional 2022 (64 位) - Current 版本 17.11.4 其他: 二、测试目的 将基于C++创建DLL库,封装到C#生成的exe中。 一般C++创建的库,在C#中使用,都是采用DllImport导入的,且要求库处…...

完美解决:.vmx 配置文件是由 VMware 产品创建,但该产品与此版 VMware Workstation 不兼容
参考文章:该产品与此版 VMware Workstation 不兼容,因此无法使用 问题描述 当尝试使用 VMware Workstation 打开别人的虚拟机时,可能会遇到以下报错: 此问题常见于以下场景: 从其他 VMware 版本(如 ESX…...

使用大语言模型对接OA系统,实现会议室预定功能
随着人工智能技术的不断进步,越来越多的企业开始借助 AI 助手来提高工作效率,尤其是在日常事务的自动化处理中。比如,在许多公司里,会议室的预定是一个常见且频繁的需求,通常需要员工手动检查空闲时间并做出选择。而通…...

Ryu控制器:L2交换功能实现案例
基于 Ryu控制器 在 VM1--OVS--VM2 的简单拓扑中实现流量自动下发(流表动态安装)的完整案例。通过该案例,当VM1与VM2首次通信时,Ryu控制器会动态学习路径并下发流表,后续流量将直接由交换机转发,无需控制器介…...
Android Wi-Fi 连接失败日志分析
1. Android wifi 关键日志总结 (1) Wi-Fi 断开 (CTRL-EVENT-DISCONNECTED reason3) 日志相关部分: 06-05 10:48:40.987 943 943 I wpa_supplicant: wlan0: CTRL-EVENT-DISCONNECTED bssid44:9b:c1:57:a8:90 reason3 locally_generated1解析: CTR…...
逻辑回归:给不确定性划界的分类大师
想象你是一名医生。面对患者的检查报告(肿瘤大小、血液指标),你需要做出一个**决定性判断**:恶性还是良性?这种“非黑即白”的抉择,正是**逻辑回归(Logistic Regression)** 的战场&a…...

AI Agent与Agentic AI:原理、应用、挑战与未来展望
文章目录 一、引言二、AI Agent与Agentic AI的兴起2.1 技术契机与生态成熟2.2 Agent的定义与特征2.3 Agent的发展历程 三、AI Agent的核心技术栈解密3.1 感知模块代码示例:使用Python和OpenCV进行图像识别 3.2 认知与决策模块代码示例:使用OpenAI GPT-3进…...
QMC5883L的驱动
简介 本篇文章的代码已经上传到了github上面,开源代码 作为一个电子罗盘模块,我们可以通过I2C从中获取偏航角yaw,相对于六轴陀螺仪的yaw,qmc5883l几乎不会零飘并且成本较低。 参考资料 QMC5883L磁场传感器驱动 QMC5883L磁力计…...

2.Vue编写一个app
1.src中重要的组成 1.1main.ts // 引入createApp用于创建应用 import { createApp } from "vue"; // 引用App根组件 import App from ./App.vue;createApp(App).mount(#app)1.2 App.vue 其中要写三种标签 <template> <!--html--> </template>…...

现代密码学 | 椭圆曲线密码学—附py代码
Elliptic Curve Cryptography 椭圆曲线密码学(ECC)是一种基于有限域上椭圆曲线数学特性的公钥加密技术。其核心原理涉及椭圆曲线的代数性质、离散对数问题以及有限域上的运算。 椭圆曲线密码学是多种数字签名算法的基础,例如椭圆曲线数字签…...
Java入门学习详细版(一)
大家好,Java 学习是一个系统学习的过程,核心原则就是“理论 实践 坚持”,并且需循序渐进,不可过于着急,本篇文章推出的这份详细入门学习资料将带大家从零基础开始,逐步掌握 Java 的核心概念和编程技能。 …...
基于matlab策略迭代和值迭代法的动态规划
经典的基于策略迭代和值迭代法的动态规划matlab代码,实现机器人的最优运输 Dynamic-Programming-master/Environment.pdf , 104724 Dynamic-Programming-master/README.md , 506 Dynamic-Programming-master/generalizedPolicyIteration.m , 1970 Dynamic-Programm…...
Hive 存储格式深度解析:从 TextFile 到 ORC,如何选对数据存储方案?
在大数据处理领域,Hive 作为 Hadoop 生态中重要的数据仓库工具,其存储格式的选择直接影响数据存储成本、查询效率和计算资源消耗。面对 TextFile、SequenceFile、Parquet、RCFile、ORC 等多种存储格式,很多开发者常常陷入选择困境。本文将从底…...

初探Service服务发现机制
1.Service简介 Service是将运行在一组Pod上的应用程序发布为网络服务的抽象方法。 主要功能:服务发现和负载均衡。 Service类型的包括ClusterIP类型、NodePort类型、LoadBalancer类型、ExternalName类型 2.Endpoints简介 Endpoints是一种Kubernetes资源…...