【Linux C编程-高级篇】换行回车探讨printf行缓冲write函数掉电保护线程安全相关

news2024/12/22 22:42:26

换行回车探讨

  • \r : 回车,定位到本行开头
  • \n : 换行,光标移到下一行
  • \r\n : 将光标移动到下一行开头
  • windows 下,每行结尾 \r\n
  • 类unix,每行结尾 \n
  • Mac系统,每行结尾\r

\r\n,windows下好像改善了,使得Linux下文件即便只有\n在windows下也能正确显示

结论:统一用 \n 就可以

printf行缓冲

  • printf末尾不加\n就无法及时将信息输出到屏幕,是因为行缓冲的存在【windows上无,类unix上才有】
  • ANSI C中将 \n 认为是行刷新标记,printf函数直至行满或遇到\n才会自动刷新输出流。
  • 要么在printf函数后加上\n,要么使用下面两种方式
    • fflush ( stdout ); // 刷新标准输出缓冲区
    • setvbuf ( stdout, nullptr, _IONBF, 0 ); // 禁止printf缓冲区【标准输出缓冲区】,使得printf直接输出

write()系统调用思考

多个进程同时调用write()往日志写数据:是否会造成数据混乱

  • 多个进程同时调用write()往日志写数据是否会产生数据混乱?通过让父子进程同时在死循环内执行日志写测试进行测试。

  • 多个进程同时写一个文件,可能会出现数据覆盖、混乱等情况,保证数据不混乱不覆盖需要以下几点:

    • a) ngx_log.fd = open ( ( const char * ) plogname, O_WRONLY | O_APPEND | O_CREAT, 0644 );
      • O_APPEND 这个标记能保证多个进程操作同一个文件时不会相互覆盖
    • b) 内核write()是系统调用,是原子操作,线程安全
    • c) 父进程fork()产生的子进程,父子进程是亲缘关系,共享文件表项
  • 资料:《Unix环境高级编程 第三版》 第三章:文件IO 3.10-3.12,涉及到了文件共享、原子操作以及函数dup、dup2的讲解

    • 第八章:进程控制 8.3 涉及到了fork函数

write()写的安全问题:数据是否被成功写入磁盘

  • write和物理磁盘间,存在着程序缓冲区内核缓冲区,write先将数据从程序缓冲区写入内核缓冲区,然后返回,内核会在一定时间后刷新一次内核缓冲,将内核缓冲数据实际写入到物理磁盘中,即数据在内核缓冲区没有写到磁盘之前,即便write函数返回,也不表示数据一定写到磁盘了

write_写磁盘.jpg

write_内核缓冲区.jpg

  • 为了确保内核缓冲区数据能及时写入磁盘,内核设置了写入时间上限,当到达这个时间上限后,内核会将内核缓冲区的脏数据全部写入磁盘,这些跟脏数据、写入时间有关的文件 在目录 /proc/sys/vm/dirty*

  • 目前代码并没有强制写磁盘,后续会讲,所以还是存在突然断电数据没有写入磁盘的可能性

掉电导致write数据丢失破解法

O_DERICT、O_SYNC、缓存同步技术

  • O_DERICT: open参数,绕过内核缓冲区,直接访问物理磁盘,但是可想而知效率肯定低

write_掉电保护O_DIRECT.jpg

  • O_SYNC: open参数,同步选项,只对write有效,是每次write操作等待物理IO完成,将掉电等问题造成的损失减到最小

write_掉电保护O_SYNC.jpg

不管用哪个,都要注意:每次写磁盘数据,务必要大块大块写,一般512-4k 4k写;【一个扇区是512B】,不要每次写几个字节,否则会被抽死******

前两个方法都不推荐,因为实时写入磁盘的方式都很慢,且违背 了操作系统设置 内核缓冲区的初衷
  • 缓存同步:尽量保证缓存数据和写到磁盘上的数据一致

    • sync(void): 将所有修改过的块缓冲区排入写队列,然后返回,并不等待实际写磁盘操作结束,数据是否写入磁盘没有保证
    • fsync(int fd): 将fd对应的文件的块缓冲区立即写入磁盘,并等待实际写磁盘操作结束返回**********
    • fdatasync(int fd): 类似于fsync,但只影响文件的数据部分。而fsync除数据外,还会同步更新文件属性【文件属性和文件数据是分开存放在两个文件的,所以fdatasync要比fsync快,不关心文件属性时可以使用fdatasync】
  • fsync( int fd ) 的正确使用姿势

      假设整个文件4M,先执行1000次write(4k)
      再执行1次fsync ( fd )
    

对于我们写的小的日志系统,没必要动用缓存同步技术,即便断电丢失几条日志也不是很重要

所以日志中只用write就足够了,而且随着win系统的发展,基本上write后去查看磁盘的时候已经写入了

应对掉电问题的方法,在大型数据库文件中需要特别注意,此时就需要用到缓存同步技术

标准IO库

// fopen, flose
// fread, fwrite
// fflush
// fseek
// fgetc, getc, getchar
// fputc, put, putchar
// fgets, gets
// printf, fprintf, sprintf
// scanf, fscanf, sscanf

fwrite 与 write 区别:

  • fwrite 是标准IO库函数,一般在stdio.h
  • write 是系统调用

fwrite等标准IO库函数又加了一层Clib缓冲,非线程安全,因此不建议使用,用的不好会导致数据写入混乱

而write等系统调用由于其原子性操作,是线程安全的,结合O_APPEND标志就可以正常写入数据

【注意是父子进程,如果是不相干进程依旧有可能乱序,具体建议看书参考学习:《Linux/Unix系统编程手册上》 第13章对也有对IO缓存比较清晰的描述 】

标准IO库函数加入的Clib缓冲如图示

标准IO库函数_Clib缓冲.jpg

标准IO库与系统调用、缓冲等如图示

标准IO库与系统调用.jpg

IO缓冲小结

标准IO库_IO缓冲小结.jpg

书籍总结

  • 资料:《Unix环境高级编程 第三版》 第三章:文件IO 3.10-3.12,涉及到了文件共享、原子操作以及函数dup、dup2的讲解
    • 第八章:进程控制 8.3 涉及到了fork函数
  • 《Linux/Unix系统编程手册上》 第13章 IO缓存

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

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

相关文章

全文最详细的Apache的管理及优化Web(图文详解)

目录 前言 一、Apache的安装及启用 二、Apache的基本信息 三、Apache的基本配置及修改 1、默认发布文件 2、Apache端口修改 3、默认发布目录 三、Apache的访问控制 1、基于客户端ip的访问控制 2、基于用户认证 四、Apache的虚拟主机 五、Apache的语言支持 六…

React--》超详细教程——React脚手架的搭建与使用

目录 React脚手架的创建 全局安装创建 npx安装创建(官方推荐) 指定React版本安装 脚手架文件介绍 React脚手架是开发现代Web应用的必备,其充分利用Webpack、Babel、ESlint等工具辅助项目的开发,当然这些工具也无需手动配置即可使用,脚手…

Java 在云原生中的内存问题

Java 凭借着自身活跃的开源社区和完善的生态优势,在过去的二十几年一直是最受欢迎的编程语言之一。步入云原生时代,蓬勃发展的云原生技术释放云计算红利,推动业务进行云原生化改造,加速企业数字化转型。 然而 Java 的云原生转型之…

Word目录自动生成,不使用word默认样式的,且指定从某页开始为第一页

文章目录一, 设置正文页为第1页:二,自动生成目录。拓展:需求:文章或者论文往往会先写好标题,摘要,写好内容。最后需要生成目录。但是这样布局后,生成的目录的起始页码不是从第1 页开…

ChatGPT通俗笔记:从GPT-N、RL之PPO算法到instructGPT、ChatGPT

前言 自从我那篇BERT通俗笔记一经发布,然后就不断改、不断找人寻求反馈、不断改,其中一位朋友倪老师(之前我司NLP高级班学员现课程助教老师之一)在谬赞BERT笔记无懈可击的同时,给我建议到,“后面估计可以尝试尝试在BERT的基础上&…

搭建OpenCV环境和Jupyter Notebook

使用Anaconda搭建python和OpenCV环境安装Anaconda,全程下一步,修改了一下默认安装路径,修改为D:\Program Files\Anaconda3同时设置了环境变量,将三个文件夹路径都加到了系统环境变量,path中。打开【开始】菜单&#xf…

MatrixVT:Efficient Multi-Camera to BEV Transformation for 3D Perception——论文笔记

参考代码:BEVDepth 1. 概述 介绍:这篇文章对LSS方法中的瓶颈项进行分析,分别指出其中显存占用问题源自于“lift”操作生成的高维度特征,运行耗时是由于“splat”操作的求和操作,对此文章从矩阵变换的角度对原版的LSS方…

Java面向对象复习

文章目录一、类和对象1. 面向对象2. 类的定义3. 对象的创建4. 类在内存中的存储5.类的成员使用6. toString()方法7. static 关键字静态成员变量静态成员方法二、封装1. 构造方法概念基本使用构造方法的重载this关键字2. private3. 封装的好处三、继承1. 继承的概念2. extends3.…

二维矩阵的元素和

二维矩阵的元素和1.背景2.原理3.实现1.背景 对矩阵元素进行求和,或者求子矩阵的元素和;给定矩阵左上角坐标(x1,y1)和右下角坐标(x2,y2); 如何快速求出 以(x1,y1),&#…

SAP入门技术分享五:内表

内表1. 概要2. 内表与表头3.内表的类型(1)类型(2)标准表(3)排序表(4)哈希表4.比较内表速度(1)标准表与排序表(2)二分法查找&#xff0…

Kafka生产者分区

生产者分区 分区的原因 (1)便于合理使用存储资源,每个Patition在一个Broker上存储,可以把海量的数据按照分区切割成一块一块数据存储在多台Broker上。合理控制分区的任务,可以实现负载均衡的效果。 (2)提高并行度&am…

如何设计一个消息队列?

本文已经收录到Github仓库,该仓库包含计算机基础、Java基础、多线程、JVM、数据库、Redis、Spring、Mybatis、SpringMVC、SpringBoot、分布式、微服务、设计模式、架构、校招社招分享等核心知识点,欢迎star~ Github地址:https://github.com/…

用户登录、注册的简单案例: html+css+MyBatis+Servlet

用户登录一. 用户登录1. 流程与思路基本流程:详细过程:2. 准备环境建库建表Pojo实体类User:Maven坐标:mybatis核心配置文件:代理接口:3. 编写目录:HTML:Serlvet:4. 效果二…

【Leetcode】21. 合并两个有序链表

【Leetcode】21. 合并两个有序链表题目思路代码题目 思路 归并排序比较两个单链表每一个节点,将较小元素的节点值封装成一个新的节点添加到一个新的链表中如果两个单链表长度不一致,也就是有一个链表指针指向null ,那么将另一个链表中的所有节点全部添加…

【手写 Vue2.x 源码】第二十四篇 - 异步更新流程

一,前言 上篇,介绍了 Vue依赖收集的视图更新部分,主要涉及以下几点: 视图初始化时: render方法中会进行取值操作,进入 Object.defineProperty 的 get 方法get 方法中为数据添加 dep,并记录当…

20230115英语学习

Gold From Old Sim Cards Could Help Make Future Drugs SIM卡中回收的黄金,可用于制造药品 Chemists are paving a road to recycle discarded SIM cards, not for electronics, but for medicine. SIM cards, which allow your phone to connect to your netwo…

ATTCK 05

环境搭建 自行下载安装包 解压VMware中win7 win8 同样方法所要用到的攻击机为kali 调节kali的网络适配器为vmnet8 调节win7的网络适配器 增加vmnet5用来连接内网win8 vmnet5名称ip角色kali192.168.115.129攻击机win7192.168.115.150192.168.138.136win8192.168.138.138DC拓…

【 java 反射上篇】java反射机制不难吧?来看看这篇

📋 个人简介 💖 作者简介:大家好,我是阿牛,全栈领域优质创作者。😜📝 个人主页:馆主阿牛🔥🎉 支持我:点赞👍收藏⭐️留言&#x1f4d…

BMS系统—产生原因如何工作

1 为什么需要BMS系统 1.1 介绍 1)BMS,battery management system,电池管理系统 2)BMS是一套嵌入式系统,由硬件和软件共同组成 3)BMS功能:管理多节锂电池组成的电池包,实现充放电管理、安全保护…

jsp动物园网上购票系统Myeclipse开发mysql数据库web结构java编程计算机网页项目

一、源码特点 JSP 动物园网上购票系统 是一套完善的web设计系统,对理解JSP java编程开发语言有帮助,系统采用web模式开发,系统具有完整的源代码和数据库,系统主要采用B/S模式开发。开发环境为TOMCAT7.0,Myeclipse8.5开发&#x…