首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >如何暂停创建新线程直到旧线程结束

如何暂停创建新线程直到旧线程结束
EN

Stack Overflow用户
提问于 2018-05-02 18:26:09
回答 2查看 69关注 0票数 3

背景

我有一个非常大的二进制数据文件(20+ GB),需要解析、处理数据,然后编写输出。我很少有经验处理如此大量的数据,虽然我在概念化如何处理这些数据时遇到了一些困难,但我确实有一个想法。注意:输入数据包含从IBM大型机检索的许多记录,因此它的格式如下:

每个记录的前4个字节(行/行)是RDW (记录描述符字)。RDW包含记录的长度(包括RDW)。由于RDW,即使文件是一个恒定的字节流,我也知道每个记录的结束位置。我可以将这个二进制文件转换为文本文件,将每两个字节转换为十六进制表示,还可以在记录的末尾包含一个新的行字符,但我担心如果这样翻译一个20+ GB二进制文件会有多大。

因为我想将该文件保留为二进制文件,所以我有一个想法:

  1. 使用一个“主”线程顺序读取文件。
  2. 一旦主服务器到达记录的末尾(使用在RDW中找到的信息),它就会产生一个新的"worker“线程,将它从文件中读取的数据传递给线程。
    • 工作线程解析数据,处理数据,并输出到某个地方。(我想把数据放在SQLite数据库中。)

  1. 当工作线程工作时,主线程继续读取文件,当它完成读取另一个记录时,它会产生第二个工作线程来处理第二个记录。这种情况一直持续到所有记录都已处理完毕。

问题

不幸的是,我想到了一个问题。读取的“主”线程将比它生成的线程工作得快得多,我担心会创建太多的线程。为了防止这种情况,我设想了这个解决方案(用伪代码):

代码语言:javascript
运行
复制
record = file.ReadRecord()
if(numberOfRunningWorkerThreads < MAX_THREADS)
    SpawnWorkerThread(record);
else
    WaitUntil(numberOfRunningWorkerThreads < MAX_THREADS)

但是,我不知道如何实现这样的功能,特别是最后一个else条件。我不熟悉多线程和异步,我甚至不知道这两个术语之间有什么区别。

谁能给我指明正确的方向?

EN

回答 2

Stack Overflow用户

发布于 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

票数 2
EN

Stack Overflow用户

发布于 2018-05-02 18:57:59

Solution1:

使用ThreadPool。设置MaxThreads,其中

设置可以并发活动的线程池的请求数。在线程池线程可用之前,该数目以上的所有请求都将保持排队状态。

类似于:

代码语言:javascript
运行
复制
System.Threading.ThreadPool.SetMaxThreads(50, 1000);
// inside loop
ThreadPool.QueueUserWorkItem(ProcessRequest);
// end loop

其中,ProcessRequest是您完成工作的方法。

Solution2:

如果您知道记录的数量:使用Parallel.For并相应地设置MaxDegreeOfParallelism

代码语言:javascript
运行
复制
Parallel.For(0, 1000, new ParallelOptions { MaxDegreeOfParallelism = 10 },
i => { 
    ProcessRequest(i);
});
票数 2
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/50141227

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档