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

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 系统提供了各种外设的控制方式&#xff0c;其中包括文件的读写&#xff0c;存储文件的介质可以是 SSD 固态硬盘或者是 EMMC 等。 其中常用的写文件方式是同步写操作&#xff0c;但是如果是写大文件会对 CPU 造成比较大的负荷&#xff0c;采用异步写的方式比较…...

Liveweb视频汇聚平台支持WebRTC协议赋能H.265视频流畅传输

随着科技的飞速发展和网络技术的不断革新&#xff0c;视频监控已经广泛应用于社会各个领域&#xff0c;成为现代安全管理的重要组成部分。在视频监控领域&#xff0c;视频编码技术的选择尤为重要&#xff0c;它不仅关系到视频的质量&#xff0c;还直接影响到视频的传输效率和兼…...

SQL组合查询

本文讲述如何利用 UNION 操作符将多条 SELECT 语句组合成一个结果集。 1. 组合查询 多数 SQL 查询只包含从一个或多个表中返回数据的单条 SELECT 语句。但是&#xff0c;SQL 也允许执行多个查询&#xff08;多条 SELECT 语句&#xff09;&#xff0c;并将结果作为一个查询结果…...

方正畅享全媒体新闻采编系统 screen.do SQL注入漏洞复现

0x01 产品简介 方正畅享全媒体新闻生产系统是以内容资产为核心的智能化融合媒体业务平台,融合了报、网、端、微、自媒体分发平台等全渠道内容。该平台由协调指挥调度、数据资源聚合、融合生产、全渠道发布、智能传播分析、融合考核等多个平台组成,贯穿新闻生产策、采、编、发…...

【机器学习】【集成学习——决策树、随机森林】从零起步:掌握决策树、随机森林与GBDT的机器学习之旅

这里写目录标题 一、引言机器学习中集成学习的重要性 二、决策树 (Decision Tree)2.1 基本概念2.2 组成元素2.3 工作原理分裂准则 2.4 决策树的构建过程2.5 决策树的优缺点&#xff08;1&#xff09;决策树的优点&#xff08;2&#xff09;决策树的缺点&#xff08;3&#xff0…...

Flink执行模式(批和流)如何选择

DataStream API支持不同的运行时执行模式(batch/streaming),你可以根据自己的需求选择对应模式。 DataStream API的默认执行模式就是streaming,用于需要连续增量处理并且预计会一直保持在线的无界(数据源输入是无限的)作业。 而batch执行模式则用于有界(输入有限)作业…...

LeetCode:101. 对称二叉树

跟着carl学算法&#xff0c;本系列博客仅做个人记录&#xff0c;建议大家都去看carl本人的博客&#xff0c;写的真的很好的&#xff01; 代码随想录 LeetCode&#xff1a;101. 对称二叉树 给你一个二叉树的根节点 root &#xff0c; 检查它是否轴对称。 示例 1&#xff1a; 输…...

LDO输入电压不满足最小压差时输出会怎样?

1、LDO最小压差 定义&#xff1a;低压差稳压器&#xff08;Low-dropout regulator&#xff0c;LDO&#xff09;LDO的最小压差Vdo指的是LDO正常工作时&#xff0c;LDO的输入电压必须高于LDO输出电压的差值&#xff0c;即Vin≥VdoVout   Vdo的值不是定值&#xff0c;会随着负载…...

源码分析之Openlayers中ZoomSlider滑块缩放控件

概述 ZoomSlider滑块缩放控件就是Zoom缩放控件的异形体&#xff0c;通过滑块的拖动或者点击滑槽&#xff0c;实现地图的缩放&#xff1b;另外其他方式控制地图缩放时&#xff0c;也会引起滑块在滑槽中的位置改变&#xff1b;即ZoomSlider滑块缩放控件会监听地图的缩放级别&…...

在Win11系统上安装Android Studio

诸神缄默不语-个人CSDN博文目录 下载地址&#xff1a;https://developer.android.google.cn/studio?hlzh-cn 官方安装教程&#xff1a;https://developer.android.google.cn/studio/install?hlzh-cn 点击Next&#xff0c;默认会同时安装Android Studio和Android虚拟机&#…...

华为ensp--BGP路径选择-AS_Path

学习新思想&#xff0c;争做新青年&#xff0c;今天学习的是BGP路径选择-AS_Path 实验目的: 理解AS_Path属性的概念 理解通过AS_Path属性进行选路的机制 掌握修改AS_Path属性的方法 实验内容: 本实验模拟了一个运营商网络场景&#xff0c;所有路由器都运行BGP协议&#xff…...

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 开发中的精髓&#xff0c;有绑定才有所谓的数据驱动。 1 . 背景 目前 wpf 界面可视化的控件&#xff0c;继承关系如下&#xff0c; 控件的数据绑定&#xff0c;基本上都要借助于 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时&#xff0c;是否遇到过以下这种问题&#xff1f; 去现场配置WIFI发现没带电脑&#xff0c;无法联网❌ 首次配置WIFI时需使用网线连电脑&#xff0c;不够快捷❌ 而博达智联为解决该类问题&#xff0c;专研了一款网关配网工具&#xff0c;实现用户现场使用手机…...

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 完整流程总结&#xff08;重点整合&#xff09;(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)的用法

当前内容所在位置&#xff08;可进入专栏查看其他译好的章节内容&#xff09; 第四部分 视觉增强技术 ✔️【第 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&#xff08;Plain Old Java Objects&#xff0c;普通老式 …...

深入剖析AI大模型:大模型时代的 Prompt 工程全解析

今天聊的内容&#xff0c;我认为是AI开发里面非常重要的内容。它在AI开发里无处不在&#xff0c;当你对 AI 助手说 "用李白的风格写一首关于人工智能的诗"&#xff0c;或者让翻译模型 "将这段合同翻译成商务日语" 时&#xff0c;输入的这句话就是 Prompt。…...

中南大学无人机智能体的全面评估!BEDI:用于评估无人机上具身智能体的综合性基准测试

作者&#xff1a;Mingning Guo, Mengwei Wu, Jiarun He, Shaoxian Li, Haifeng Li, Chao Tao单位&#xff1a;中南大学地球科学与信息物理学院论文标题&#xff1a;BEDI: A Comprehensive Benchmark for Evaluating Embodied Agents on UAVs论文链接&#xff1a;https://arxiv.…...

Qt Widget类解析与代码注释

#include "widget.h" #include "ui_widget.h"Widget::Widget(QWidget *parent): QWidget(parent), ui(new Ui::Widget) {ui->setupUi(this); }Widget::~Widget() {delete ui; }//解释这串代码&#xff0c;写上注释 当然可以&#xff01;这段代码是 Qt …...

深入理解JavaScript设计模式之单例模式

目录 什么是单例模式为什么需要单例模式常见应用场景包括 单例模式实现透明单例模式实现不透明单例模式用代理实现单例模式javaScript中的单例模式使用命名空间使用闭包封装私有变量 惰性单例通用的惰性单例 结语 什么是单例模式 单例模式&#xff08;Singleton Pattern&#…...

【Linux】自动化构建-Make/Makefile

前言 上文我们讲到了Linux中的编译器gcc/g 【Linux】编译器gcc/g及其库的详细介绍-CSDN博客 本来我们将一个对于编译来说很重要的工具&#xff1a;make/makfile 1.背景 在一个工程中源文件不计其数&#xff0c;其按类型、功能、模块分别放在若干个目录中&#xff0c;mak…...

Java详解LeetCode 热题 100(26):LeetCode 142. 环形链表 II(Linked List Cycle II)详解

文章目录 1. 题目描述1.1 链表节点定义 2. 理解题目2.1 问题可视化2.2 核心挑战 3. 解法一&#xff1a;HashSet 标记访问法3.1 算法思路3.2 Java代码实现3.3 详细执行过程演示3.4 执行结果示例3.5 复杂度分析3.6 优缺点分析 4. 解法二&#xff1a;Floyd 快慢指针法&#xff08;…...

[USACO23FEB] Bakery S

题目描述 Bessie 开了一家面包店! 在她的面包店里&#xff0c;Bessie 有一个烤箱&#xff0c;可以在 t C t_C tC​ 的时间内生产一块饼干或在 t M t_M tM​ 单位时间内生产一块松糕。 ( 1 ≤ t C , t M ≤ 10 9 ) (1 \le t_C,t_M \le 10^9) (1≤tC​,tM​≤109)。由于空间…...

Java数组Arrays操作全攻略

Arrays类的概述 Java中的Arrays类位于java.util包中&#xff0c;提供了一系列静态方法用于操作数组&#xff08;如排序、搜索、填充、比较等&#xff09;。这些方法适用于基本类型数组和对象数组。 常用成员方法及代码示例 排序&#xff08;sort&#xff09; 对数组进行升序…...

OpenGL-什么是软OpenGL/软渲染/软光栅?

‌软OpenGL&#xff08;Software OpenGL&#xff09;‌或者软渲染指完全通过CPU模拟实现的OpenGL渲染方式&#xff08;包括几何处理、光栅化、着色等&#xff09;&#xff0c;不依赖GPU硬件加速。这种模式通常性能较低&#xff0c;但兼容性极强&#xff0c;常用于不支持硬件加速…...

【AI News | 20250609】每日AI进展

AI Repos 1、OpenHands-Versa OpenHands-Versa 是一个通用型 AI 智能体&#xff0c;通过结合代码编辑与执行、网络搜索、多模态网络浏览和文件访问等通用工具&#xff0c;在软件工程、网络导航和工作流自动化等多个领域展现出卓越性能。它在 SWE-Bench Multimodal、GAIA 和 Th…...