如何确定我的所有线程何时完成执行?
Posted
技术标签:
【中文标题】如何确定我的所有线程何时完成执行?【英文标题】:How do I determine when all of my threads have finished executing? 【发布时间】:2011-10-25 23:23:44 【问题描述】:我的架构可以从打包的二进制文件中读取数据包,根据数据包类型将每个数据包分配给单独的处理管道,然后将数据包重新组合到管道另一端的新文件中。每个管道包含类似于this one.的阻塞队列
在每个管道中的阻塞队列的每一侧都有一个线程,该线程运行一个循环,对数据包进行排队或出队。这些线程从控制器对象异步启动(即“即发即忘”风格)。此控制器对象有一个 Dictionary<int, ChannelPipeline>
集合,其中包含所有管道对象。
这是我的问题:我可以设置什么机制来告诉我所有管道何时完成处理?每个管道上都有一个EndOfData
属性;我是否必须在每个管道上不断轮询该属性,直到它们都读取true
,还是有更好(即更有效)的方法?
【问题讨论】:
让EndOfData
和AutoResetEvent
和WaitHandle.WaitAll()
成为你的朋友。
@Hans Passant:除非他有超过 64 个管道(或 WaitHandles),否则WaitAll() 似乎不允许同时等待更多句柄。
【参考方案1】:
如果知道管道总数可以考虑AutoResetEvent
+ 整数计数器
AutoResetEvent allThreadsDone = new AutoResetEvent(false);
int completedThreads;
int scheduledThreads;
基本上每个工作线程都会增加它使用的值Interlocked.Increment()
并设置事件以防它是最后一个线程:
Interlocked.Increment(ref completedThreads);
if (completedThreads == scheduledThreads)
allThreadsDone.Set();
在监控线程中你只需这样做:
allThreadsDone.WaitOne();
// here is we know that all threads are finished
【讨论】:
不,这只会阻止线程完成。信号量的计数方式错误。 @Hans Passant :是的,我解决了这个问题,基本上完全删除了使用信号量的想法,因为看不到信号量已满/空的处理方式 补充一点,如果您使用的是 .NET 4.0,您还可以使用 CountdownEvent class,它似乎只提供了该功能。以上是关于如何确定我的所有线程何时完成执行?的主要内容,如果未能解决你的问题,请参考以下文章