让我们假设我们有下一个任务(非常抽象):
我们有一个文件夹与各种数量的文件要处理(文件数可能是1,2,或几千)。每个文件只能按顺序处理(这意味着不可能在内存中读取整个文件并在多个线程中处理)。文件处理的结果应生成新文件,并按顺序写入。如何使用所有可用的CPU核心?
我只看到两种方法:
块处理不是很快的操作,比读取慢。
操作系统: Mac/Linux,也许是Windows。
哪种方法更好?我们还有其他解决办法吗?
发布于 2017-06-26 10:29:05
最好的方法是编写一个简单的Task类,它可以独立完成整个操作(读、处理、写),这样就不会与外部的、线程不安全的操作有任何联系。然后使用一个任务队列,其中固定数量的线程可以获取这些任务并处理它们。很多线程通常是核心* 2。
可以从数学上证明,选项2总是等于或慢于基于任务的解决方案,而且在任何情况下都会更加复杂。唯一选项2更可行的情况是线程切换成为实际的瓶颈。也就是说,如果您的服务器具有类似于1000个并发但有状态的连接,但只有一个网卡,那么让一个网络线程为1000个处理线程提供信息,而不是唤醒通过行发送的每一个字节上的1000个线程,就更有效了。
基于任务的解决方案还使度量吞吐量和比较其他线程如何影响吞吐量变得更加容易,因为您可以简单地以任务/秒来度量。
发布于 2017-06-26 10:03:47
最简单的有效解决方案可能是只有一个读取器线程,其优先级低于默认优先级。如果有一个免费的CPU核心,它就可以运行。这将创建一个工作线程(处理一个输入文件并将其写回)。当这些线程以默认优先级运行时,这将实现自平衡。当所有CPU都忙于处理文件时,读取器线程将没有多少CPU时间,因此生成的新工作线程不多。
分离文件处理并将它们写回磁盘没有真正的意义;这只会产生大量未写入的工作排队在内存中的可能性。
发布于 2017-06-26 12:53:07
这两种方法各有优缺点。
单读取器
处理线程中的读取:
顺便说一句,有更多可能的处理方案。您忘记提到的一个是有一个编写线程,其中您的处理转储将导致队列,并让后台进程编写它。这可能会给你带来额外的刺激。没有必要让每个线程都等待写入。
您还可以使用在一个队列中写入的并行读取器,而不是这个队列中的处理(甚至更复杂的编程:-),但在某些情况下可以工作。
平行作家也可以工作。
此外,还可以在不同的本地磁盘(不是目录,而是物理磁盘)之间分发文件。如果并行执行,这肯定会提高您的读/写性能。
https://stackoverflow.com/questions/44756934
复制相似问题