共享文件夹场景下双线程操作的同步必要性及相关问题咨询
问题解答
1. 4KB文件创建+写入操作的耗时范围
这个耗时没有固定标准,完全取决于存储介质、操作系统、文件系统以及当前系统的IO负载,常见场景下的耗时范围如下:
- NVMe固态硬盘:空载场景下约1μs ~ 20μs
- SATA固态硬盘:空载场景下约10μs ~ 100μs
- 机械硬盘:空载场景下约1ms ~ 10ms,若存在IO排队可能上升到几十甚至上百ms
- 网络共享目录(NFS/SMB等):波动极大,从几毫秒到数百毫秒都有可能,受网络状态、远端存储负载影响非常明显
注意:无论平均耗时多短,都存在偶发的IO阻塞可能,不能通过估算耗时的方式规避竞态问题。
2. 同步机制的必要性
这个场景必须做同步处理,绝对不能靠调整删除线程扫描间隔、估算写入耗时的方式来规避问题,核心原因是操作系统的IO调度是不可预测的:哪怕平均写入耗时只有10微秒,也可能因为系统突然出现高优先级IO任务抢占资源,导致你的写入操作被阻塞数十毫秒甚至更久,只要概率不为0,就一定会出现删除未写完文件的问题。
你可以选择几种轻量的同步方案,不需要引入复杂的跨线程互斥锁:
- 临时文件原子重命名:写入线程先将内容写入后缀为
.tmp的临时文件,写入完成后再调用rename操作重命名为目标格式的文件名,删除线程仅扫描目标格式的文件即可。同文件系统下的rename是原子操作,不会出现半完成的文件被扫描到的问题。 - 文件锁:写入线程创建文件后加排他写锁,写入完成后再释放锁;删除线程扫描到文件后先尝试加共享读锁,加锁成功再处理文件,失败就跳过等待下次扫描。
- 写入完成标记:写入时先在文件头写入固定长度的占位符,全部内容写入完成后再回头把文件头的占位符改成约定好的完成标记;删除线程读取文件时先校验文件头的完成标记,存在才处理,否则跳过等待下次扫描。
内容的提问来源于stack exchange,提问作者i chik
相关产品推荐
相关产品推荐

