多进程写同一个日志并发问题分析

本文分析了在多进程环境下,使用C语言库函数写入日志时可能出现的时序问题,主要原因是flush操作的非原子性。通过对系统调用和库函数的深入探讨,揭示了write的原子性和flush的潜在风险。提出了两种优化方案:一是手动加锁刷新,二是定时线程刷新,以解决日志乱序问题。
摘要由CSDN通过智能技术生成

背景问题

在优化日志组件项目中有如下场景:两个进程,A、B进程往同一个文件写日志的时候,使用C语言的库函数写,fopen文件追加方式打开, fwrite等。如果每一次写的时候都强制fflush操作,则写的时序是正常的。如果不是每次fflush操作的时候,则会出现写入日志的时候的时序问题,即是A进程的一条日志没打完,B进程的日志中间插进来了。

问题分析

原子性

  • 系统调用
    先从最基本的系统调用说起,磁盘IO效率的简单分析,该篇的问题2中提到,如果是系统调用,多进程需要保证写磁盘有序,则需要open的时候使用O_APPEND选项,其本质是open的时候,写磁盘的时候会锁住文件的inode节点,全局唯一,所以进程间可以实现互斥。

  • 库函数IO
    对于C语言的库函数而言,它在系统调用的上层,做了一层缓冲。之所以自己做一层缓冲,是为了提升IO效率,在用户空间就对数据进行缓冲,最终使用合并写操作,以提升IO的效率。而多进程同时写文件的时候,由于flush的时机,由库函数自动决定,因此,多进程状态下,存在刷新操作的非原子性问题。

追问

库函数的追加写不是通过O_APPEND方式打开的吗?为什么这里刷新操作为什么不是原子的, 底层不是通过锁定innode方式实现的吗?

评论 4
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值