C++ 查找线程之间的最小队列大小

C++ 查找线程之间的最小队列大小,c++,multithreading,scheduling,task-queue,C++,Multithreading,Scheduling,Task Queue,我正在尝试用多线程实现一种新的调度技术。每个线程都有自己的私有本地队列。其思想是,每次从程序线程创建任务时,它都应该在队列中搜索最小队列大小(任务数较少的队列),并在其中排队。 线程间负载平衡的一种方法,较不繁忙的队列排队较多 你能从编程的角度提出一些逻辑(或想法)如何在给定的队列中动态地找到最小大小的队列吗 我在Visual Studio 2008,C++编程语言中工作,在我们自己的多线程库中实现了多速率同步数据流范例。 为什么线程没有从“主”工作队列中获取它们的工作? 如果您真的试图将工作项

我正在尝试用多线程实现一种新的调度技术。每个线程都有自己的私有本地队列。其思想是,每次从程序线程创建任务时,它都应该在队列中搜索最小队列大小(任务数较少的队列),并在其中排队。 线程间负载平衡的一种方法,较不繁忙的队列排队较多

你能从编程的角度提出一些逻辑(或想法)如何在给定的队列中动态地找到最小大小的队列吗


我在Visual Studio 2008,C++编程语言中工作,在我们自己的多线程库中实现了多速率同步数据流范例。

为什么线程没有从“主”工作队列中获取它们的工作?


如果您真的试图将工作项从一个主源分发到一组工作程序,那么您就是在进行负载平衡,正如您所说的。在这种情况下,您实际上是在谈论日程安排,除非您只是简单地执行循环式平衡。调度是计算中一个非常深入的主题,你可以很容易地花数周或数月的时间来学习它

如果您真的想尝试这个方法,那么每个队列是否可以保留一个公共的“int count”成员,在推送/弹出任务时使用原子inc/dec进行更新


另一个问题是,当一个任务排队到一个线程,而该线程恰好在运行一个特别长的作业,而另一个线程正要将一个非常短的作业出列时,这样的设计是否值得管理开销和偶尔的“错误”

您可以在线程之间同步计数器。但我想这不是你想要的

因为您希望使用数据流实现所有内容,所以所有内容都应该是队列

第一个选项是查询队列中的作业数。如果您想要一个读写器模式,我认为这并不容易,因为您可能需要为这个操作使用锁,而这不是您想要的。注意:我只是猜测,这里不能使用无锁队列;你要么有一个计数器,要么取两个指针的差,不管怎样,你都有一个锁


您的第二个选项(可以使用无锁代码完成)是向调度程序线程发回一个命令,告诉他工作线程x已经消耗了一个作业。使用这种方法,您将有n个以上的队列,每个队列从一个工作线程到调度程序线程。

正如您所看到的,试图找到负载较低的队列非常麻烦,并且可能是一种低效的方法,因为您可能会在只有一项繁重任务的情况下向队列添加更多工作,而具有小任务的队列将不会有更多的作业,并很快变得不活跃

您最好使用工作窃取启发式方法:当一个线程完成自己的作业时,它将查看其他线程队列并“窃取”一些工作,而不是保持空闲或被终止

然后系统将自动平衡,每个线程都处于活动状态,直到没有足够的工作给每个人


您不应该出现空闲线程和等待处理的工作的情况。

是否有不能在所有线程中使用单个队列的原因?这样就不会出现平衡队列大小的问题。@NPE:对于多个队列,您可以使用单写器/读取器模式有效地实现它们。@使用线程本地队列的NPEyes将使用单写器/读取器模式有效地实现每个线程我猜OP希望使用无锁队列,并希望消除锁开销将超过队列迭代开销和不正确的排队决策,当另一个线程空闲时,将作业留在队列中,交给忙碌的线程。我不相信这是一个好的设计,但我没有尝试过类似的设计,所以我不确定。这就像为每个队列创建一个私有int计数,在推送任务时增加其计数,在弹出时减少其计数,并且任务被分派到看到此计数的队列。是-迭代队列并将任务分派到计数最低(或找到的第一个零)的队列。正如您所说,没有完全同步,但是可能是最简单、最有效的解决方案。@MartinJames:是的,正如你所说的另一个问题将是一个问题,因为我们不知道每个任务的确切执行时间。但是我认为线程执行的任务的处理时间通常是相等的?这是真的吗?@rahul,我不知道-它们是你的任务,你应该知道:)在你的第二个选项中,你说“你还有n个队列,每个队列从一个工作线程到调度线程”。我不清楚。你能解释一下吗clear@rahul:目前每个线程有一个队列,对吗?您可以为每个线程添加另一个队列,因此每个线程有两个队列。一个用于将作业发送到线程,另一个用于通知调度程序线程队列中有一个作业被消耗。+1,这更好,但使用无锁队列实现更复杂-队列有多个使用者。我知道偷工池是存在的,只是不知道它们内部是如何工作的。