【问题标题】:Multi threaded application in C++C++ 中的多线程应用程序
【发布时间】:2012-11-02 15:18:08
【问题描述】:

我正在开发一个用 C++ 编写的多线程应用程序。我使用一些临时文件在我的线程之间传递数据。一个线程将要处理的数据写入目录中的文件。另一个线程扫描目录中的工作文件并读取文件并进一步处理它们,然后删除这些文件。我必须使用这些文件,因为如果我的应用程序在什么时候被杀死,我必须保留尚未处理的数据。

但我讨厌使用多个文件。我只想使用一个文件。一个线程连续写入文件,另一个线程读取数据并删除已读取的数据。 就像从顶部和底部填充容器一样,我可以从容器中获取和删除数据。如何在 C++ 中有效地做到这一点,首先有没有办法..?

【问题讨论】:

  • 你需要使用文件吗?为什么不使用互斥锁来保护它的内存呢?
  • 另一种方法可能是使用数据库(SQLite、SQL Server CE、...)
  • 如果您的应用程序被终止并且您正在使用缓冲 IO,我会警告您,您需要担心的事情比您最初想象的要多。
  • 我不能使用内存,当我的应用程序被杀死时我不能丢失数据,而且由于数据会泛滥,将它写入数据库是个好主意吗?
  • 数据库可能比文件更适合它们可以从多个线程访问,并且有事务的概念。事务确保 ACID(原子的、一致的、隔离的、持久的)——我猜这就是你要找的。​​span>

标签: c++ multithreading file-io


【解决方案1】:

正如 cmets 对您的问题所建议的那样,使用 SQLite 之类的数据库可能是一个非常好的解决方案。 但是,如果您坚持使用文件,那么这当然是可能的。

我自己做过一次 - 使用文件在磁盘上创建了一个持久队列。

以下是有关如何实现此目的的指南:

  1. 文件应包含一个标题,该标题指向下一个未处理的记录(条目)和下一个可写入的位置。
  2. 如果记录的长度可变,则每条记录都应包含一个标明记录长度的标头。
  3. 您可能希望为每条记录添加一个标志,表明该记录是否已处理
  4. 文件锁定可用于确保没有人读取正在写入的文件部分
  5. 使用低级 IO - 不要使用任何类型的缓冲流,使用直接写入语义

这里是读写的方案(可能有一些小的逻辑错误,但你应该能够从那里得到它):

阅读器

  1. 锁定文件头并读取它并重新解锁
  2. 转到最后一个记录位置
  3. 读取记录头和记录
  4. 在打开已处理标志的情况下写回记录头
  5. 如果您不在文件末尾锁定标题并写入下一个未处理记录的新位置,否则写入一些标记以指示没​​有更多记录要处理
  6. 确保要写入的下一条记录指向正确的位置

您可能还希望阅读器偶尔为您压缩文件:

  1. 锁定整个文件
  2. 将所有未处理的记录复制到文件的开头(您可能希望保留一些逻辑,以免覆盖未处理的记录 - 仅当已处理空间大于未处理空间时才可能压缩)
  3. 更新标题
  4. 解锁文件

作家

  1. 锁定文件头,查看下一条记录写入的位置,然后解锁
  2. 将文件从要写入的地方锁定到记录的长度
  3. 写记录解锁
  4. 如果未处理的记录标记表明没有要处理的记录,则锁定标题让它指向新记录解锁标题

希望这能让你走上写作之路

【讨论】:

    【解决方案2】:

    【讨论】:

    • 对不起,我忘了说我的应用程序也需要在 Linux 上运行。
    • 在unix系统中也有类似的API:见mmap
    【解决方案3】:

    您可以编写每行处理行的数据,每行的分隔符指示此记录是否处理

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2010-10-12
      • 2018-09-05
      • 1970-01-01
      • 2018-12-17
      相关资源
      最近更新 更多