线程安全文件读写:使用文件名/锁字典,还是只捕获 IOExceptions?

Posted

技术标签:

【中文标题】线程安全文件读写:使用文件名/锁字典,还是只捕获 IOExceptions?【英文标题】:thread-safe file reads and writes: use a filename/lock dictionary, or just catch IOExceptions? 【发布时间】:2020-09-09 07:57:23 【问题描述】:

我有一些进程会定期将行附加到文件中,还有一些进程会定期读取这些文件。这些文件并不大,而且追加频繁但很小。

我可以在循环延迟计数器中捕获 IOExceptions,或者我可以使用静态 ConcurrentDictionary 来防止发生争用。

捕获异常是最严格的,但我担心最终会读取到不完整的写入。使用锁字典更安全还是没有必要?

【问题讨论】:

当你让它正常工作时,为什么要破解它? ConcurrentDictionary 无法跨进程执行此操作,请使用命名互斥体来仲裁访问。 我正在考虑使用在文件系统和访问文件系统之间的服务层,这将允许字典工作 - 我没有提到作者和读者可以在不同的机器上。命名互斥锁确实摆脱了对字典的需求,但尚不清楚我如何直接允许使用它进行多次读取。也许我不需要支持。 【参考方案1】:

如果您担心阅读不完整的内容,您可以随时使用file.Open 和FileShare.None/Fileshare.Read。这与重试一起应该是安全的,但如果存在争用可能会很慢。

创建服务可能是最巧妙的解决方案。在这种情况下,我会将所有写入/读取委托给服务,如果可能的话缓存文件,并使用队列来写出更改。

如果服务在某处丢失消息并且未释放锁,则仅使用服务来管理锁可能会很危险。

【讨论】:

以上是关于线程安全文件读写:使用文件名/锁字典,还是只捕获 IOExceptions?的主要内容,如果未能解决你的问题,请参考以下文章

第8章 读写锁

Springboot Java多线程操作本地文件,加读写锁,阻塞的线程等待运行中的线程执行完再查询并写入

读写锁自旋锁

Java——多线程高并发系列之ReadWriteLock读写锁

Java——多线程高并发系列之ReadWriteLock读写锁

C# 多线程同步访问一个文件怎么处理