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%

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/890174.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

曲线的测地曲率

测地曲率 设 S : r ( u , v ) S:r(u,v) S:r(u,v)是曲面&#xff0c; γ ( s ) r ( u ( s ) , v ( s ) ) \gamma(s)r(u(s),v(s)) γ(s)r(u(s),v(s))是 S S S上的一条弧长参数化曲线。 1.称 K g ( s ) D γ ˙ d s ( γ ( s ) ) T \mathbb{K}_g(s)\frac{D\dot{\gamma}}{d\b…

js常用方法之: 预览大图(uniapp原生方法封装)

方法: //预览图片 pic可传单个图片地址字符串 或 图片数组(带index) previewPic: function(pic, index) {if (!pic) return;if (index undefined) {let array [];array.push(pic);uni.previewImage({urls: array,current: array[0]});} else {uni.previewImage({urls: pic,…

重拾设计模式--原型模式

文章目录 原型模式定义原型模式UML图优点缺点使用场景C 代码示例深拷贝、浅拷贝 原型模式定义 用原型实例指定创建对象的种类&#xff0c;并且通过拷贝这些原型创建新的对象&#xff1b; 核心中的核心就是 克隆clone ,后面讲 原型模式是一种创建型设计模式&#xff0c;它的主要…

flutter --no-color pub get 超时解决方法

新建Flutter项目后&#xff0c;运行报错&#xff0c;需要执行pub get 点击Run ‘flutter pub get’ … … … 卡着&#xff0c;不动了&#xff0c;提示超时 是因为墙的问题 解决方案&#xff1a; 添加以下环境变量 变量名: PUB_HOSTED_URL 变量值: https://pub.flutter-io.cn …

如何详细步骤地进行Z-Blog博客系统的安装过程?

安装Z-Blog博客系统的步骤如下&#xff1a; 下载Z-Blog软件包&#xff1a;根据你的操作系统&#xff0c;选择相应的Z-Blog软件包进行下载。在Z-Blog官方网站上&#xff0c;你可以找到最新版本的Z-Blog软件包。 解压软件包&#xff1a;将下载的Z-Blog软件包解压到你的服务器或本…

【C++】优先级队列以及仿函数

本篇我们来介绍一下优先级队列 priority_queue 。优先级队列的底层是数据结构中的堆&#xff0c;在C中它是一个容器适配器&#xff0c;这个容器适配器比之前的栈和队列更复杂。 1.priority_queue的介绍 1.1 优先级队列的底层 因为优先级队列就是堆&#xff0c;堆的底层是数组…

CompletableFuture小记

文章目录 概述Thread 和 RunnableThreadRunnableThread 和 Runnable 的关系小问题 Callable、Future 和 FutureTaskCallableFutureTaskFuture接口Callable 和 FutureTask 的关系Thread 、Runnable、FutureTask 和 Callable 的关系 CompletableFuture常用方法概述get() 和 join(…

不需要服务器,使用netlify快速部署自己的网站

Netlify简介 1.1 Netlify的功能与特点 Netlify 是一个功能强大的静态网站托管平台&#xff0c;它不仅提供了简单的网站部署功能&#xff0c;还集成了许多现代化的开发工具和服务&#xff0c;帮助开发者更高效地构建、部署和管理网站。Netlify 的核心功能包括&#xff1a; 自动…

sudo apt-get update 报错及解决

sudo apt-get update报错及解决工作笔记 一、问题现象 在执行 sudo apt-get update 命令时&#xff0c;终端出现一系列报错信息&#xff1a; 从 http://archive.ubuntu.com/ubuntu 相关多个仓库&#xff08;如 xenial InRelease、xenial-security InRelease、xenial-updates…

简单工厂模式和策略模式的异同

文章目录 简单工厂模式和策略模式的异同相同点&#xff1a;不同点&#xff1a;目的&#xff1a;结构&#xff1a; C 代码示例简单工厂模式示例&#xff08;以创建图形对象为例&#xff09;策略模式示例&#xff08;以计算价格折扣策略为例&#xff09;UML区别 简单工厂模式和策…

leetcode 3285 找到稳定山的下标

3285. 找到稳定山的下标 已解答 简单 相关标签 相关企业 有 n 座山排成一列&#xff0c;每座山都有一个高度。给你一个整数数组 height &#xff0c;其中 height[i] 表示第 i 座山的高度&#xff0c;再给你一个整数 threshold 。 对于下标不为 0 的一座山&#xff0c;如果…

Unity动态读取外部图片转Texture2D,内存过大问题解决方案

问题描述 加载原始图片2.63M的图片,分辨率为3023*4032,占用内存108.5M 加载原始图片12.6 M的图片,分辨率为6000*8000,占用内存427.2M 太恐怖了吧 解决方案 1.加载完图片,等比缩放,宽高改为1024或者512以下 1024占用5.2M,512占用1.3M,相比小了很多 2.原始Texture2…

linux-----进程及基本操作

进程的基本概念 定义&#xff1a;在Linux系统中&#xff0c;进程是正在执行的一个程序实例&#xff0c;它是资源分配和调度的基本单位。每个进程都有自己独立的地址空间、数据段、代码段、栈以及一组系统资源&#xff08;如文件描述符、内存等&#xff09;。进程的组成部分&am…

ArkTs组件的学习

一. AlphabetIndexer 可以与容器组件联动用于按逻辑结构快速定位容器显示区域的组件 参数名类型必填说明arrayValueArray<string>是字母索引字符串数组&#xff0c;不可设置为空selectednumber是初始选中项索引值若超出索引值范围则取默认值0 class Lxr{tImg:Resource…

cusolver SP 与 cuSPARSE 函数库的关系

NVIDIA 提供的 cuSPARSE 和 cuSOLVER 函数库都是用于处理稀疏矩阵的高性能计算库&#xff0c;但它们的功能和用途有所不同。以下是这两个库的关系和各自的功能概述&#xff1a; 1. cuSPARSE 函数库 定义&#xff1a;cuSPARSE 是 NVIDIA 的一个库&#xff0c;专门用于稀疏矩阵的…

裸金属服务器和传统服务器的区别

本文将来探讨一下裸金属服务器与传统服务器两者之间的区别&#xff0c;并且讲解一下裸金属服务器和传统服务器各自的优势都有哪些&#xff01; 首先&#xff0c;裸金属服务器是一种没有虚拟化层的服务器架构&#xff0c;用户能够直接访问和管理服务器的物理资源&#xff1b;而传…

51c自动驾驶~合集42

我自己的原文哦~ https://blog.51cto.com/whaosoft/12888355 #DriveMM 六大数据集全部SOTA&#xff01;最新DriveMM&#xff1a;自动驾驶一体化多模态大模型&#xff08;美团&中山大学&#xff09; 近年来&#xff0c;视觉-语言数据和模型在自动驾驶领域引起了广泛关注…

Unity3D实现接口类的应用例子

系列文章目录 unity工具 文章目录 系列文章目录👉前言👉一、效果如下👉二、使用步骤👉2-1、创建接口👉2-2、创建具体的可交互物体类 Door(门,实现 IInteractable 接口)👉2-3、创建另一个具体的可交互物体类 Chest(宝箱,同样实现 IInteractable 接口)👉三、…

Linux限制root 用户的远程登录(安全要求)

前言&#xff1a;现在基本用户主机都不允许使用root来操作&#xff0c;所以本文通过创建新用户&#xff0c;并限制root用户的ssh来解决这个问题 1. 创建新账户 aingo 首先&#xff0c;使用 root 账户登录系统。 sudo useradd aingo设置 aingo 账户密码&#xff1a; sudo pa…

前端学习笔记-Vue篇-04

4 Vue中的ajax 4.1 解决开发环境Ajax跨域问题 vue脚手架配置代理 配置参考 | Vue CLI方法一&#xff1a;在vue.config.js中添加如下配置: module.exports {devServer: {proxy: http://localhost:4000} } 说明: 1.优点:配置简单&#xff0c;请求资源时直接发给前端(8080)即…