Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/multithreading/4.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Multithreading 从多个线程写入文件。_Multithreading_Async Await_Concurrent Queue - Fatal编程技术网

Multithreading 从多个线程写入文件。

Multithreading 从多个线程写入文件。,multithreading,async-await,concurrent-queue,Multithreading,Async Await,Concurrent Queue,我有一个应用程序A,它调用另一个应用程序B,该应用程序执行一些计算并写入file.txt文件 A通过多个线程调用B的多个实例,每个实例尝试写入同一个file.txt文件 实际问题来了: 由于多个线程试图访问同一个文件,因此文件访问会抛出常见的错误 我尝试了一种在singleton类中使用并发队列的方法,B的每个实例都会添加到队列中,该类中的另一个线程负责从队列中删除项目并写入file.txt文件。同步获取队列,写入操作成功。这个很好用 如果队列中有太多线程和太多项目,则文件写入工作正常,但如果由

我有一个应用程序A,它调用另一个应用程序B,该应用程序执行一些计算并写入file.txt文件 A通过多个线程调用B的多个实例,每个实例尝试写入同一个file.txt文件 实际问题来了: 由于多个线程试图访问同一个文件,因此文件访问会抛出常见的错误

我尝试了一种在singleton类中使用并发队列的方法,B的每个实例都会添加到队列中,该类中的另一个线程负责从队列中删除项目并写入file.txt文件。同步获取队列,写入操作成功。这个很好用

如果队列中有太多线程和太多项目,则文件写入工作正常,但如果由于某种原因,队列崩溃或突然停止,则应该写入文件的所有信息都将丢失

如果我在不使用队列的情况下使文件从B同步写入,那么它会很慢,因为它需要检查文件锁定,但在这里,由于B立即写入文件,所以丢失数据的可能性较小

有什么最好的方法或设计来处理这种情况?文件写入完成后,我不需要响应。我不能让B等待文件写入完成


异步等待文件写入在这里有用吗

我认为你所做的是最好的。如果仍然存在问题,您可能必须调整生产者/消费者队列解决方案,但在我看来,您使用这种方法做得相当好

如果内存队列不是答案,那么将其外部化到消息队列和侦听器池可能是一种改进

关系数据库和事务管理器就是为了解决这个问题而诞生的。为什么继续使用基于文件的解决方案?是否有可能探索一种替代方案

是否有更好的方法或设计来处理此场景

您可以让每个生产者线程写入它自己的滚动文件,而不是将操作排队。每X秒生产者移动到新文件,一些聚合线程就会唤醒,读取(每个生产者的)以前的文件,并将结果写入最终的
File.txt
输出文件。此处不需要读/写锁

这确保了安全恢复,因为滚动文件在您处理和删除它们之前一直存在

这也意味着您总是向磁盘写入数据,这比在内存中排队执行任务和成批向磁盘写入数据要慢得多但这是您为一致性付出的代价。

异步等待文件写入在这里有用吗

使用异步IO与此无关。您提到的问题是1)共享资源(输出文件)和2)缺乏一致性(当队列崩溃时),异步编程都与此无关

异步之所以出现在图中是因为我不想因为这个文件写入操作而延迟B的现有工作


async确实可以帮助您实现这一点。无论您选择实现什么模式(以解决原始问题),只要使用异步IO api,它都可以始终是异步的。

如果您从不关心上一次写入是否已完成,您可以按照建议异步执行。例如,在后台任务中。为此,您需要某种形式的并发锁。因此,所有多线程B实例调用异步操作并在不等待异步文件写入完成的情况下继续其循环可以吗?如果是的话,你能提供一些例子吗?很抱歉,回复有点晚,但这应该给你一个线索:。基本上,您可以创建一个共享锁,然后在每次写入文件之前锁定它(然后释放)。如果一个线程想在锁被占用时写入,您可以延迟它(当前线程)直到锁再次可用。或者,您可以检查文件是否正在使用:而不是使用显式锁对象-如果您的应用程序不是唯一访问文件的应用程序,这将非常有用。仅当除消息队列之外没有其他选项时,我们必须使用数据库。我们可以使用您提到的方法生成不同的文件。但是我们已经有了碎片问题,这就像我们期望的文件在千个范围内一样。所以我们放弃了每个线程/调用一个文件的计划。异步之所以出现在图中是因为我不想因为这个文件写入操作而延迟B的现有工作。因此,考虑将文件写入交给此异步方法,并让B像以前一样继续它的工作。对于文件写入,我使用信号量处理锁问题。感谢您查找Pronlem,我们还必须同时从另一个应用程序读取此文件。因此,如果文件被拆分,然后写入一个单独的文件,我们可能无法轻松地实现要求perfect@user3689864请参见上面的添加内容。另外,您当前的实现如何解决碎片问题?我这样问是因为它似乎没有:)