背景
我有一个非常大的二进制数据文件(20+ GB),需要解析、处理数据,然后编写输出。我很少有经验处理如此大量的数据,虽然我在概念化如何处理这些数据时遇到了一些困难,但我确实有一个想法。注意:输入数据包含从IBM大型机检索的许多记录,因此它的格式如下:
每个记录的前4个字节(行/行)是RDW (记录描述符字)。RDW包含记录的长度(包括RDW)。由于RDW,即使文件是一个恒定的字节流,我也知道每个记录的结束位置。我可以将这个二进制文件转换为文本文件,将每两个字节转换为十六进制表示,还可以在记录的末尾包含一个新的行字符,但我担心如果这样翻译一个20+ GB二进制文件会有多大。
因为我想将该文件保留为二进制文件,所以我有一个想法:
问题
不幸的是,我想到了一个问题。读取的“主”线程将比它生成的线程工作得快得多,我担心会创建太多的线程。为了防止这种情况,我设想了这个解决方案(用伪代码):
record = file.ReadRecord()
if(numberOfRunningWorkerThreads < MAX_THREADS)
SpawnWorkerThread(record);
else
WaitUntil(numberOfRunningWorkerThreads < MAX_THREADS)但是,我不知道如何实现这样的功能,特别是最后一个else条件。我不熟悉多线程和异步,我甚至不知道这两个术语之间有什么区别。
谁能给我指明正确的方向?
发布于 2018-05-02 18:46:19
我相信你正在寻找一个信号量(或者也许SemaphoreSlim也可以为你工作)。信号量“限制可以同时访问资源或资源池的线程数量。信号量是用特定数目的插槽创建的。然后,您可以调用"WaitOne“来等待可用的插槽,而当使用一个插槽完成时,可以调用"Release”。如果没有可用的插槽,"WaitOne“可以永远等待,或者直到超时。
因此,在您的示例中,主线程将调用WaitOne以等待可用的插槽。然后,在工作线程的末尾,您可以调用Release来释放一个插槽。
.NET信号量:https://msdn.microsoft.com/en-us/library/system.threading.semaphore(v=vs.110).aspx
.NET SemaphoreSlim (轻量级信号量):https://msdn.microsoft.com/en-us/library/system.threading.semaphoreslim(v=vs.110).aspx
发布于 2018-05-02 18:57:59
Solution1:
使用ThreadPool。设置MaxThreads,其中
设置可以并发活动的线程池的请求数。在线程池线程可用之前,该数目以上的所有请求都将保持排队状态。
类似于:
System.Threading.ThreadPool.SetMaxThreads(50, 1000);
// inside loop
ThreadPool.QueueUserWorkItem(ProcessRequest);
// end loop其中,ProcessRequest是您完成工作的方法。
Solution2:
如果您知道记录的数量:使用Parallel.For并相应地设置MaxDegreeOfParallelism。
Parallel.For(0, 1000, new ParallelOptions { MaxDegreeOfParallelism = 10 },
i => {
ProcessRequest(i);
});https://stackoverflow.com/questions/50141227
复制相似问题