Linux C 程序 【05】异步写文件
1.开发背景
Linux 系统提供了各种外设的控制方式,其中包括文件的读写,存储文件的介质可以是 SSD 固态硬盘或者是 EMMC 等。
其中常用的写文件方式是同步写操作,但是如果是写大文件会对 CPU 造成比较大的负荷,采用异步写的方式比较合适,并且需要直接越过内核,直接通过 IO 访问,直接访问磁盘,关键词 O_DIRECT。可以有效降低 CPU 的使用率。
#ifdef __USE_GNU
# define O_DIRECT __O_DIRECT /* Direct disk access. */
# define O_NOATIME __O_NOATIME /* Do not set atime. */
# define O_PATH __O_PATH /* Resolve pathname but do not open file. */
# define O_TMPFILE __O_TMPFILE /* Atomically create nameless file. */
#endif
添加宏定义,否者 O_DIRECT 显示未定义
#define _GNU_SOURCE
2.开发需求
设计实验:
1)使用同步写硬盘的方式连续 100MB 的数据 10 次并统计每次写入的时间和速度
2)使用异步写硬盘的方式连续 100MB 的数据 10 次并统计每次写入的时间和速度
3.开发环境
ubuntu20.04 + RK3568 + Linux4.19.232 + 金士顿 SSD
4.实现步骤
4.1 实现代码
#define _GNU_SOURCE#include <stdio.h>
#include <stdlib.h>
#include <fcntl.h>
#include <unistd.h>
#include <string.h>
#include <errno.h>
#include <linux/fs.h>
#include <sys/time.h>#include "com_file.h"
#include "app_log.h"#define BUFFER_SIZE (1024 * 1024 * 100) // 100MB
#define TEST_FILE_PATH "/run/media/sata/output.dat"/* 同步写测试 */
static void test_write_sync(char *file_path, char *buffer)
{/* 创建文件和路径 */common_file_create(file_path);/* 打开文件 */int fd = open(file_path, O_WRONLY | O_CREAT, 0644);if (fd < 0) {alog_error("open failed\r\n");return;}/* 写数据 */if (write(fd, buffer, BUFFER_SIZE) != BUFFER_SIZE) {alog_error("write failed\r\n");close(fd);return;}/* 关闭文件 */close(fd);
}/* 异步写测试 */
static void test_write_async(char *file_path, char *buffer)
{/* 创建文件和路径 */common_file_create(file_path);/* 打开文件 */int fd = open(file_path, O_WRONLY | O_CREAT | O_DIRECT, 0644);if (fd < 0) {alog_error("open failed\r\n");return;}/* 写数据 */if (write(fd, buffer, BUFFER_SIZE) != BUFFER_SIZE) {alog_error("write failed\r\n");close(fd);return;}/* 关闭文件 */close(fd);
}/* 主程序 */
int main()
{alog_info("%s start\r\n", __func__);char file_path[] = TEST_FILE_PATH;char *pdata_sync = NULL;char *pdata_async = NULL;/* 初始化同步内存 */pdata_sync = (char *)malloc(BUFFER_SIZE);if (pdata_sync == NULL){alog_error("malloc failed\r\n");return 1;}alog_info("sync memory init ok\r\n");/* 初始化异步内存 */if (posix_memalign((void **)&pdata_async, 512, BUFFER_SIZE) != 0) // 512 4096{alog_error("posix_memalign failed\r\n");return 1;}alog_info("async memory init ok\r\n");/* 填充数据 */for (long long int i = 0; i < BUFFER_SIZE; i++){pdata_sync[i] = i & 0xFF;pdata_async[i] = i & 0xFF;}alog_info("data init ok\r\n");/* 计时*/struct timeval start_time;struct timeval end_time;/* 同步写测试 */for (int i = 0; i < 10; i++){gettimeofday(&start_time, NULL);test_write_sync(file_path, pdata_sync);gettimeofday(&end_time, NULL);int usec_sync = (end_time.tv_sec - start_time.tv_sec) * 1000000 + (end_time.tv_usec - start_time.tv_usec);double speed_sync = (double)BUFFER_SIZE / ((double)usec_sync / 1000 / 1000);alog_info("sync[%d] write test time: %d ms, speed: %lf MB/s\r\n", i, usec_sync / 1000, speed_sync / (1024 * 1024));}/* 异步写测试 */for (int i = 0; i < 10; i++){gettimeofday(&start_time, NULL);test_write_async(file_path, pdata_async);gettimeofday(&end_time, NULL);int usec_async = (end_time.tv_sec - start_time.tv_sec) * 1000000 + (end_time.tv_usec - start_time.tv_usec);double speed_async = (double)BUFFER_SIZE / ((double)usec_async / 1000 / 1000);alog_info("async[%d] write test time: %d ms, speed: %lf MB/s\r\n", i, usec_async / 1000, speed_async / (1024 * 1024));}/* 释放内存 */free(pdata_sync);free(pdata_async);return 0;
}
4.2 测试结果

异步写硬盘速度更快,并且 CPU 占用更低,只有不到 20%,同步写硬盘 CPU 占用超过 90%
相关文章:
Linux C 程序 【05】异步写文件
1.开发背景 Linux 系统提供了各种外设的控制方式,其中包括文件的读写,存储文件的介质可以是 SSD 固态硬盘或者是 EMMC 等。 其中常用的写文件方式是同步写操作,但是如果是写大文件会对 CPU 造成比较大的负荷,采用异步写的方式比较…...
Liveweb视频汇聚平台支持WebRTC协议赋能H.265视频流畅传输
随着科技的飞速发展和网络技术的不断革新,视频监控已经广泛应用于社会各个领域,成为现代安全管理的重要组成部分。在视频监控领域,视频编码技术的选择尤为重要,它不仅关系到视频的质量,还直接影响到视频的传输效率和兼…...
SQL组合查询
本文讲述如何利用 UNION 操作符将多条 SELECT 语句组合成一个结果集。 1. 组合查询 多数 SQL 查询只包含从一个或多个表中返回数据的单条 SELECT 语句。但是,SQL 也允许执行多个查询(多条 SELECT 语句),并将结果作为一个查询结果…...
方正畅享全媒体新闻采编系统 screen.do SQL注入漏洞复现
0x01 产品简介 方正畅享全媒体新闻生产系统是以内容资产为核心的智能化融合媒体业务平台,融合了报、网、端、微、自媒体分发平台等全渠道内容。该平台由协调指挥调度、数据资源聚合、融合生产、全渠道发布、智能传播分析、融合考核等多个平台组成,贯穿新闻生产策、采、编、发…...
【机器学习】【集成学习——决策树、随机森林】从零起步:掌握决策树、随机森林与GBDT的机器学习之旅
这里写目录标题 一、引言机器学习中集成学习的重要性 二、决策树 (Decision Tree)2.1 基本概念2.2 组成元素2.3 工作原理分裂准则 2.4 决策树的构建过程2.5 决策树的优缺点(1)决策树的优点(2)决策树的缺点(3࿰…...
Flink执行模式(批和流)如何选择
DataStream API支持不同的运行时执行模式(batch/streaming),你可以根据自己的需求选择对应模式。 DataStream API的默认执行模式就是streaming,用于需要连续增量处理并且预计会一直保持在线的无界(数据源输入是无限的)作业。 而batch执行模式则用于有界(输入有限)作业…...
LeetCode:101. 对称二叉树
跟着carl学算法,本系列博客仅做个人记录,建议大家都去看carl本人的博客,写的真的很好的! 代码随想录 LeetCode:101. 对称二叉树 给你一个二叉树的根节点 root , 检查它是否轴对称。 示例 1: 输…...
LDO输入电压不满足最小压差时输出会怎样?
1、LDO最小压差 定义:低压差稳压器(Low-dropout regulator,LDO)LDO的最小压差Vdo指的是LDO正常工作时,LDO的输入电压必须高于LDO输出电压的差值,即Vin≥VdoVout Vdo的值不是定值,会随着负载…...
源码分析之Openlayers中ZoomSlider滑块缩放控件
概述 ZoomSlider滑块缩放控件就是Zoom缩放控件的异形体,通过滑块的拖动或者点击滑槽,实现地图的缩放;另外其他方式控制地图缩放时,也会引起滑块在滑槽中的位置改变;即ZoomSlider滑块缩放控件会监听地图的缩放级别&…...
在Win11系统上安装Android Studio
诸神缄默不语-个人CSDN博文目录 下载地址:https://developer.android.google.cn/studio?hlzh-cn 官方安装教程:https://developer.android.google.cn/studio/install?hlzh-cn 点击Next,默认会同时安装Android Studio和Android虚拟机&#…...
华为ensp--BGP路径选择-AS_Path
学习新思想,争做新青年,今天学习的是BGP路径选择-AS_Path 实验目的: 理解AS_Path属性的概念 理解通过AS_Path属性进行选路的机制 掌握修改AS_Path属性的方法 实验内容: 本实验模拟了一个运营商网络场景,所有路由器都运行BGP协议ÿ…...
Android Java Ubuntu系统如何编译出 libopencv_java4.so
Cmake: cd ~ wget https://github.com/Kitware/CMake/releases/download/v3.30.3/cmake-3.30.3-linux-x86_64.tar.gztar -xzvf cmake-3.30.3-linux-x86_64.tar.gz sudo ln -sf $(pwd)/cmake-3.30.3-linux-x86_64/bin/* /usr/bin/cmake --versionAndroid NDK: wget https://…...
WPF Binding 绑定
绑定是 wpf 开发中的精髓,有绑定才有所谓的数据驱动。 1 . 背景 目前 wpf 界面可视化的控件,继承关系如下, 控件的数据绑定,基本上都要借助于 FrameworkElement 的 DataContext 属性。 只有先设置了控件的 DataContext 属性&…...
算法笔记—前缀和(动态规划)
【模板】前缀和_牛客题霸_牛客网 (nowcoder.com) #include <initializer_list> #include <iostream> #include <vector> using namespace std;int main() {//输入数据int n,q;cin>>n>>q;vector<int> arr;arr.resize(n1);for(int i1;i<…...
将HTML转换为PDF:使用Spire.Doc的详细指南(二)无水印版
目录 引言 一、准备工作 1. 下载Spire.Doc for Java破解版 2. 将JAR包安装到本地Maven (1) 打开命令提示符 (2) 输入安装命令 (3) 在pom.xml中导入依赖 二、实现HTML到PDF的转换 1. 创建Java类 2. 完整代码示例 3. 代码解析 4. 处理图像 5. 性能优化 6. 错误处理…...
V900新功能-电脑不在旁边,通过手机给PLC远程调试网关配置WIFI联网
您使用BDZL-V900时,是否遇到过以下这种问题? 去现场配置WIFI发现没带电脑,无法联网❌ 首次配置WIFI时需使用网线连电脑,不够快捷❌ 而博达智联为解决该类问题,专研了一款网关配网工具,实现用户现场使用手机…...
prober.php探针
raw.githubusercontent.com/kmvan/x-prober/master/dist/prober.php...
esp8266_TFTST7735语音识别UI界面虚拟小助手
文章目录 一 实现思路1 项目简介1.1 项目效果1.2 实现方式 2 项目构成2.1 软硬件环境2.2 完整流程总结(重点整合)(1) 功能逻辑图(2) 接线(3) 使用esp8266控制TFT屏(4)TFT_espI库配置方法(5) TFT_esp库常用代码详解(6)TFT屏显示图片(7) TFT屏显示汉字(8) …...
【CSS in Depth 2 精译_086】14.3:CSS 剪切路径(clip-path)的用法
当前内容所在位置(可进入专栏查看其他译好的章节内容) 第四部分 视觉增强技术 ✔️【第 14 章 蒙版、形状与剪切】 ✔️ 14.1 滤镜 14.1.1 滤镜的类型14.1.2 背景滤镜 14.2 蒙版 14.2.1 带渐变效果的蒙版特效14.2.2 基于亮度来定义蒙版14.2.3 其他蒙版属…...
【服务器】MyBatis是如何在java中使用并进行分页的?
MyBatis 是一个支持普通 SQL 查询、存储过程和高级映射的持久层框架。它消除了几乎所有的 JDBC 代码和参数的手动设置以及结果集的检索。MyBatis 可以通过简单的 XML 或注解来配置和映射原始类型、接口和 Java 的 POJO(Plain Old Java Objects,普通老式 …...
铭豹扩展坞 USB转网口 突然无法识别解决方法
当 USB 转网口扩展坞在一台笔记本上无法识别,但在其他电脑上正常工作时,问题通常出在笔记本自身或其与扩展坞的兼容性上。以下是系统化的定位思路和排查步骤,帮助你快速找到故障原因: 背景: 一个M-pard(铭豹)扩展坞的网卡突然无法识别了,扩展出来的三个USB接口正常。…...
网络六边形受到攻击
大家读完觉得有帮助记得关注和点赞!!! 抽象 现代智能交通系统 (ITS) 的一个关键要求是能够以安全、可靠和匿名的方式从互联车辆和移动设备收集地理参考数据。Nexagon 协议建立在 IETF 定位器/ID 分离协议 (…...
Golang dig框架与GraphQL的完美结合
将 Go 的 Dig 依赖注入框架与 GraphQL 结合使用,可以显著提升应用程序的可维护性、可测试性以及灵活性。 Dig 是一个强大的依赖注入容器,能够帮助开发者更好地管理复杂的依赖关系,而 GraphQL 则是一种用于 API 的查询语言,能够提…...
测试markdown--肇兴
day1: 1、去程:7:04 --11:32高铁 高铁右转上售票大厅2楼,穿过候车厅下一楼,上大巴车 ¥10/人 **2、到达:**12点多到达寨子,买门票,美团/抖音:¥78人 3、中饭&a…...
【项目实战】通过多模态+LangGraph实现PPT生成助手
PPT自动生成系统 基于LangGraph的PPT自动生成系统,可以将Markdown文档自动转换为PPT演示文稿。 功能特点 Markdown解析:自动解析Markdown文档结构PPT模板分析:分析PPT模板的布局和风格智能布局决策:匹配内容与合适的PPT布局自动…...
OkHttp 中实现断点续传 demo
在 OkHttp 中实现断点续传主要通过以下步骤完成,核心是利用 HTTP 协议的 Range 请求头指定下载范围: 实现原理 Range 请求头:向服务器请求文件的特定字节范围(如 Range: bytes1024-) 本地文件记录:保存已…...
Axios请求超时重发机制
Axios 超时重新请求实现方案 在 Axios 中实现超时重新请求可以通过以下几种方式: 1. 使用拦截器实现自动重试 import axios from axios;// 创建axios实例 const instance axios.create();// 设置超时时间 instance.defaults.timeout 5000;// 最大重试次数 cons…...
【RockeMQ】第2节|RocketMQ快速实战以及核⼼概念详解(二)
升级Dledger高可用集群 一、主从架构的不足与Dledger的定位 主从架构缺陷 数据备份依赖Slave节点,但无自动故障转移能力,Master宕机后需人工切换,期间消息可能无法读取。Slave仅存储数据,无法主动升级为Master响应请求ÿ…...
06 Deep learning神经网络编程基础 激活函数 --吴恩达
深度学习激活函数详解 一、核心作用 引入非线性:使神经网络可学习复杂模式控制输出范围:如Sigmoid将输出限制在(0,1)梯度传递:影响反向传播的稳定性二、常见类型及数学表达 Sigmoid σ ( x ) = 1 1 +...
QT: `long long` 类型转换为 `QString` 2025.6.5
在 Qt 中,将 long long 类型转换为 QString 可以通过以下两种常用方法实现: 方法 1:使用 QString::number() 直接调用 QString 的静态方法 number(),将数值转换为字符串: long long value 1234567890123456789LL; …...
