写/读文件时的冲突

时间:2015-06-26 07:44:55

标签: c multithreading file-io concurrency

我正在用C开发一个小软件,用于在公告板中读取和写入消息。每条消息都是一个以渐进数字命名的.txt。

该软件是多线程的,有许多用户可以进行并发操作。

用户可以执行的操作是:

  1. 阅读整个公告板(所有.txt文件内容的串联)
  2. 添加消息(添加名为“id_max ++。txt”的文件)
  3. 删除邮件。删除邮件后,该号码中将有一个漏洞(例如,“1.txt”,“2.txt”,“4.txt”)将永远不会被填满。
  4. 现在,我想知道是否存在一些I / O问题(*)我应该管理(以及如何)或OS(类Unix)单独完成这一切。

    (*)例如2个想要阅读和删除同一文件的用户

2 个答案:

答案 0 :(得分:1)

更简单的解决方案是使用像sqlite或MySQL这样的数据库,这两个数据库都提供了可以用来实现一致性的事务。如果你还想沿着这条路走,请继续阅读。

问题不是IO问题,如果您没有实现适当的监视器,则会出现并发问题。考虑以下场景(它不是唯一有问题的场景,但它只是一个例子)。

  1. 用户1读取最大ID并将其存储在本地变量中。
  2. 同时,用户2读取相同的最大ID并将其存储在本地变量中。
  3. 用户1首先写入,然后用户2覆盖用户1刚写的内容,因为它对最大ID有相同的想法。
  4. 可以通过将当前最大id保持为初始化程序时初始化的变量并使用锁保护get_and_increment操作来解决此特定情况。但是,如果您采用这种方法,这不是您需要推理的唯一有问题的情况。

答案 1 :(得分:1)

由于你有类Unix,操作系统会在另一个线程打开文件时删除文件:目录条目会被立即删除,文件本身(inode)会在最后一次关闭时被删除。

我能看到的唯一问题是目录扫描和文件打开之间:竞争条件可能会导致文件被删除。

恕我直言,您只需要考虑错误文件不存在是正常的,只需转到下一个文件。

您所描述的并不是很糟糕,因为它类似于邮件的MH文件夹,并且可以通过许多不同的进程访问,即使涉及锁定。但是根据负载和消息的大小,您可以考虑使用数据库。经验法则(我的意见):

  • 少数并发访问和大文件:继续使用文件系统
  • 许多访问和小文件(几个ko max。):使用数据库

当然,在创建新邮件时,您必须使用互斥保护例程来查找下一个号码(为了注意问题,应将信用归因于@ merlin2011)。

您在评论中说您的规范不允许使用数据库。与邮件处理类比,您可以使用单个文件(如传统邮件格式):

  • 一个单一文件
  • 每条消息前面都有一个固定大小的标题,说明它是活动的还是已删除
  • 无需同步读取权限
  • 写入权限必须同步

这将是一个穷人的数据库,其中所有同步都是通过手动完成,但每个线程只有一个文件描述符并保存所有打开和关闭操作。在有许多读取和少量写入或删除的情况下,它是有意义的

可能的改进(仍然像邮件阅读器那样)来构建具有每条消息的偏移量和状态的索引。索引可以在磁盘上或内存中,具体取决于您的要求。