Multithreading “我应该把它放在哪里?”;当作业1。。n完成了吗?“;
我有一些并行代码和线程池 我分派要完成的作业组,我需要分派15个作业,比如说,当所有15个作业都完成时,应该执行这个特殊作业“作业16” 您不能将“作业16”排在最后一个队列中,让线程池“准备就绪时执行”,因为它可能会在作业13、14、15完成之前启动“作业16”的执行 所以,你需要有一种计数的方法。我的问题是,责任在哪里Multithreading “我应该把它放在哪里?”;当作业1。。n完成了吗?“;,multithreading,language-agnostic,Multithreading,Language Agnostic,我有一些并行代码和线程池 我分派要完成的作业组,我需要分派15个作业,比如说,当所有15个作业都完成时,应该执行这个特殊作业“作业16” 您不能将“作业16”排在最后一个队列中,让线程池“准备就绪时执行”,因为它可能会在作业13、14、15完成之前启动“作业16”的执行 所以,你需要有一种计数的方法。我的问题是,责任在哪里 调用代码中的:使用在每个作业结束时递增的静态/全局变量。作业1-15执行计数器+。当计数器=15时,执行作业16 在线程池中:将功能添加到线程池中,以在“之前提交的作业(时
- 调用代码中的:使用在每个作业结束时递增的静态/全局变量。作业1-15执行
。当计数器=15时,执行作业16计数器+
- 在线程池中:将功能添加到线程池中,以在“之前提交的作业(时间戳)未保留时”执行
- 在回调中:(负责检查作业1-15是否完成,否则旋转/睡眠)
- 我更喜欢第一种方法
除了计数方法,您可以使用MalualReSeEvest[]数组来同步第十六个作业和剩余的15个作业。
< P>您也可以考虑在自己的类中封装此行为,并在完成作业时引发一个事件,以触发对第十六个任务的排队,例如:internal class ParallelBatchRunner
{
public event EventHandler Completed = delegate { };
public void Run(List<Action> tasks)
{
int count = tasks.Count;
tasks.ForEach(t =>
{
Action completionTask = () =>
{
t();
if (Interlocked.Decrement(ref count) == 0)
{
Completed(this, EventArgs.Empty);
}
};
ThreadPool.QueueUserWorkItem(_ => completionTask());
});
}
}
内部类ParallelBatchRunner
{
public event EventHandler Completed=委托{};
公共作废运行(列出任务)
{
int count=tasks.count;
tasks.ForEach(t=>
{
操作完成任务=()=>
{
t();
if(联锁减量(参考计数)==0)
{
已完成(此,EventArgs.Empty);
}
};
ThreadPool.QueueUserWorkItem(=>completionTask());
});
}
}
请注意,计数器+++
不是线程安全的。你可以打个电话,我最后做了类似的事情。每个ParallelBatchRunner
都有一个计数器,当计数器达到批大小并且批中的最后一个作业完成时,将调用一个函数BatchReady()
,该函数将启动下一批。