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

fcntl()函数的概念和使用案例 c语言

在 Linux 系统编程中,fcntl() 函数(File Control)是用于操作文件描述符的核心函数,可控制文件或套接字的底层属性。它支持多种操作,包括设置非阻塞模式、获取/设置文件状态标志、管理文件锁等。以下是详细概念和使用案例:


核心概念

1. 函数原型
#include <unistd.h>
#include <fcntl.h>int fcntl(int fd, int cmd, ... /* arg */ );
  • 参数
    • fd:要操作的文件描述符(文件、管道、套接字等)。
    • cmd:控制命令(如 F_GETFLF_SETFLF_SETLK 等)。
    • arg:可选参数,具体类型取决于 cmd
  • 返回值
    • 成功:根据 cmd 不同返回不同值(如 F_GETFL 返回当前标志位)。
    • 失败:返回 -1,错误码通过 errno 获取。
2. 常用命令(cmd 参数)
命令作用
F_GETFL获取文件状态标志(如 O_RDONLYO_NONBLOCK)。
F_SETFL设置文件状态标志(只能修改部分标志,如 O_NONBLOCKO_APPEND)。
F_GETFD获取文件描述符标志(如 FD_CLOEXEC)。
F_SETFD设置文件描述符标志。
F_SETLK设置文件锁(非阻塞)。
F_SETLKW设置文件锁(阻塞)。
F_GETLK检查锁是否可设置。

使用案例

1. 设置文件描述符为非阻塞模式

常用于套接字或管道,避免 readaccept 等调用阻塞程序。

#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;
}

关键注意事项

  1. 非阻塞模式

    • 对套接字设置 O_NONBLOCK 后,acceptreadwrite 等操作会立即返回,需检查 errno 是否为 EAGAINEWOULDBLOCK
    • 示例检查非阻塞读:
      char buf[1024];
      ssize_t n = read(fd, buf, sizeof(buf));
      if (n == -1) {if (errno == EAGAIN || errno == EWOULDBLOCK) {// 无数据可读,稍后重试} else {perror("read error");}
      }
      
  2. 文件锁

    • 锁类型
      • F_RDLCK:共享读锁(允许多个进程同时读)。
      • F_WRLCK:排他写锁(独占文件)。
      • F_UNLCK:释放锁。
    • 锁继承:文件锁不会被子进程继承。
    • 锁范围l_startl_len 定义锁定区域,l_len = 0 表示到文件末尾。
  3. 原子性操作

    • fcntl 的锁操作是原子性的,适合多进程同步。
  4. 错误处理

    • 检查 fcntl 返回值,结合 errno 处理错误(如 EACCESEBADF)。

扩展案例:检查文件锁状态

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 系统编程中&#xff0c;fcntl() 函数&#xff08;File Control&#xff09;是用于操作文件描述符的核心函数&#xff0c;可控制文件或套接字的底层属性。它支持多种操作&#xff0c;包括设置非阻塞模式、获取/设置文件状态标志、管理文件锁等。以下是详细概念和使用案…...

Linux红帽:RHCSA认证知识讲解(一)RedHat背景与环境配置

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

Windows11安装GPU版本Pytorch2.6教程

1: 准备工作 针对已经安装好的Windows11系统&#xff0c;先检查Nvidia驱动和使用的CUDA版本情况。先打开Windows PowerShell&#xff0c;通过nvidia-smi命令查看GPU的情况&#xff0c;结果如下图1所示&#xff0c;从结果中可知使用的CUDA版本为12.8。 图1&#xff1a;检测安装…...

网络传输的七层协议

网络传输的七层协议是 OSI模型&#xff08;开放系统互联模型&#xff09; 中的七个层次&#xff0c;每一层都负责不同的网络功能。具体如下&#xff1a; 物理层&#xff08;Physical Layer&#xff09; 负责在物理媒介上传输比特流&#xff0c;即将数据以电信号、光信号等形式在…...

【蓝桥杯集训·每日一题2025】 AcWing 6134. 哞叫时间II python

6134. 哞叫时间II Week 1 2月20日 农夫约翰正在试图向埃尔茜描述他最喜欢的 USACO 竞赛&#xff0c;但她很难理解为什么他这么喜欢它。 他说「竞赛中我最喜欢的部分是贝茜说『现在是哞哞时间』并在整个竞赛中一直哞哞叫」。 埃尔茜仍然不理解&#xff0c;所以农夫约翰将竞赛…...

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 自…...

三数之和:经典问题的多种优化策略

三数之和&#xff1a;经典问题的多种优化策略 大家好&#xff0c;我是Echo_Wish。今天我们来聊一个经典的算法问题——三数之和&#xff08;3Sum&#xff09;。它是许多面试和算法竞赛中常见的问题之一&#xff0c;也常常考察我们对算法优化的理解和技巧。我们不仅要解决问题&…...

信息学奥赛一本通 1520:【 例 1】分离的路径 | 洛谷 P2860 [USACO06JAN]Redundant Paths G

【题目链接】 ybt 1520&#xff1a;【 例 1】分离的路径 洛谷 P2860 [USACO06JAN]Redundant Paths G 【题目考点】 1. 图论&#xff1a;割边&#xff08;桥&#xff09; 边双连通分量 【解题思路】 每个草场是一个顶点&#xff0c;草场之间的双向路是无向边&#xff0c;该…...

架构师面试(六):熔断和降级

问题 在千万日活的电商系统中&#xff0c;商品列表页服务通过 RPC 调用广告服务&#xff1b;经过统计发现&#xff0c;在最近10秒的时间里&#xff0c;商品列表页服务在对广告服务的调用中有 98% 的调用是超时的&#xff1b; 针对这个场景&#xff0c;下面哪几项的说法是正确的…...

使用 DeepSeek 生成流程图、甘特图与思维导图:结合 Typora 和 XMind 的高效工作流

在现代工作与学习中&#xff0c;可视化工具如流程图、甘特图和思维导图能够极大地提升信息整理与表达的效率。本文将详细介绍如何使用 DeepSeek 生成 Mermaid 文本&#xff0c;结合 Typora 快速生成流程图和甘特图&#xff0c;并通过 Markdown 格式生成思维导图&#xff0c;最终…...

粘贴到Word里的图片显示不全

粘贴到Word里的图片显示不全&#xff0c;可从Word设置、图片本身、软件与系统等方面着手解决&#xff0c;具体方法如下&#xff1a; Word软件设置 经实践发现&#xff0c;图片在word行距的行距出现问题&#xff0c;可以按照如下调整行距进行处理 修改段落行距&#xff1a; 选…...

【C语言】结构体内存对齐问题

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

【蓝桥杯单片机】第十三届省赛第二场

一、真题 二、模块构建 1.编写初始化函数(init.c) void Cls_Peripheral(void); 关闭led led对应的锁存器由Y4C控制关闭蜂鸣器和继电器 2.编写LED函数&#xff08;led.c&#xff09; void Led_Disp(unsigned char ucLed); 将ucLed取反的值赋给P0 开启锁存器 关闭锁存…...

类与对象(5)

上一章是类与对象&#xff08;4&#xff09;-CSDN博客 深入了构造函数和静态成员&#xff0c;大概讲解了类型转换 最后一章最后一章 友元 在 C 中&#xff0c;友元提供了一种突破类的访问控制&#xff08;封装&#xff09;的方式。通过友元&#xff0c;外部的函数或类可以访…...

AI知识架构之数据采集

数据采集 数据格式: 结构化数据:以固定格式和结构存储,如数据库中的表以及 Excel 表格,易于查询和分析。半结构化数据:有一定结构但不如结构化数据严格,XML 常用于数据交换,JSON 在 Web 应用中广泛用于数据传输和存储。非结构化数据:无预定义结构,文本、图像、音频和视…...

细说STM32F407单片机2个ADC使用DMA同步采集各自的1个输入通道的方法

目录 一、示例说明 二、工程配置 1、RCC、DEBUG、CodeGenerator 2、USART6 3、TIM3 &#xff08;1&#xff09;Mode &#xff08;2&#xff09;参数设置 &#xff08;3&#xff09; TRGO &#xff08;4&#xff09;ADC1_IN0 1&#xff09;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 不兼容

参考文章&#xff1a;该产品与此版 VMware Workstation 不兼容&#xff0c;因此无法使用 问题描述 当尝试使用 VMware Workstation 打开别人的虚拟机时&#xff0c;可能会遇到以下报错&#xff1a; 此问题常见于以下场景&#xff1a; 从其他 VMware 版本&#xff08;如 ESX…...

使用大语言模型对接OA系统,实现会议室预定功能

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

Ryu控制器:L2交换功能实现案例

基于 Ryu控制器 在 VM1--OVS--VM2 的简单拓扑中实现流量自动下发&#xff08;流表动态安装&#xff09;的完整案例。通过该案例&#xff0c;当VM1与VM2首次通信时&#xff0c;Ryu控制器会动态学习路径并下发流表&#xff0c;后续流量将直接由交换机转发&#xff0c;无需控制器介…...

浏览器访问 AWS ECS 上部署的 Docker 容器(监听 80 端口)

✅ 一、ECS 服务配置 Dockerfile 确保监听 80 端口 EXPOSE 80 CMD ["nginx", "-g", "daemon off;"]或 EXPOSE 80 CMD ["python3", "-m", "http.server", "80"]任务定义&#xff08;Task Definition&…...

Python:操作 Excel 折叠

💖亲爱的技术爱好者们,热烈欢迎来到 Kant2048 的博客!我是 Thomas Kant,很开心能在CSDN上与你们相遇~💖 本博客的精华专栏: 【自动化测试】 【测试经验】 【人工智能】 【Python】 Python 操作 Excel 系列 读取单元格数据按行写入设置行高和列宽自动调整行高和列宽水平…...

在 Nginx Stream 层“改写”MQTT ngx_stream_mqtt_filter_module

1、为什么要修改 CONNECT 报文&#xff1f; 多租户隔离&#xff1a;自动为接入设备追加租户前缀&#xff0c;后端按 ClientID 拆分队列。零代码鉴权&#xff1a;将入站用户名替换为 OAuth Access-Token&#xff0c;后端 Broker 统一校验。灰度发布&#xff1a;根据 IP/地理位写…...

工程地质软件市场:发展现状、趋势与策略建议

一、引言 在工程建设领域&#xff0c;准确把握地质条件是确保项目顺利推进和安全运营的关键。工程地质软件作为处理、分析、模拟和展示工程地质数据的重要工具&#xff0c;正发挥着日益重要的作用。它凭借强大的数据处理能力、三维建模功能、空间分析工具和可视化展示手段&…...

MODBUS TCP转CANopen 技术赋能高效协同作业

在现代工业自动化领域&#xff0c;MODBUS TCP和CANopen两种通讯协议因其稳定性和高效性被广泛应用于各种设备和系统中。而随着科技的不断进步&#xff0c;这两种通讯协议也正在被逐步融合&#xff0c;形成了一种新型的通讯方式——开疆智能MODBUS TCP转CANopen网关KJ-TCPC-CANP…...

Axios请求超时重发机制

Axios 超时重新请求实现方案 在 Axios 中实现超时重新请求可以通过以下几种方式&#xff1a; 1. 使用拦截器实现自动重试 import axios from axios;// 创建axios实例 const instance axios.create();// 设置超时时间 instance.defaults.timeout 5000;// 最大重试次数 cons…...

Java入门学习详细版(一)

大家好&#xff0c;Java 学习是一个系统学习的过程&#xff0c;核心原则就是“理论 实践 坚持”&#xff0c;并且需循序渐进&#xff0c;不可过于着急&#xff0c;本篇文章推出的这份详细入门学习资料将带大家从零基础开始&#xff0c;逐步掌握 Java 的核心概念和编程技能。 …...

自然语言处理——Transformer

自然语言处理——Transformer 自注意力机制多头注意力机制Transformer 虽然循环神经网络可以对具有序列特性的数据非常有效&#xff0c;它能挖掘数据中的时序信息以及语义信息&#xff0c;但是它有一个很大的缺陷——很难并行化。 我们可以考虑用CNN来替代RNN&#xff0c;但是…...

libfmt: 现代C++的格式化工具库介绍与酷炫功能

libfmt: 现代C的格式化工具库介绍与酷炫功能 libfmt 是一个开源的C格式化库&#xff0c;提供了高效、安全的文本格式化功能&#xff0c;是C20中引入的std::format的基础实现。它比传统的printf和iostream更安全、更灵活、性能更好。 基本介绍 主要特点 类型安全&#xff1a…...

RKNN开发环境搭建2-RKNN Model Zoo 环境搭建

目录 1.简介2.环境搭建2.1 启动 docker 环境2.2 安装依赖工具2.3 下载 RKNN Model Zoo2.4 RKNN模型转化2.5编译C++1.简介 RKNN Model Zoo基于 RKNPU SDK 工具链开发, 提供了目前主流算法的部署例程. 例程包含导出RKNN模型, 使用 Python API, CAPI 推理 RKNN 模型的流程.   本…...