5

我需要建立一个工人系统(表示为线程)和(多个)队列。单个作业在其中一个队列中等待,并等待工作线程处理它们。每个工作人员只能处理一些队列中的作业。没有旋转等待。C/C++、pthreads、标准 POSIX。

对我来说,问题是“多个队列”的事​​情。我知道如何用一个队列来实现它。工作人员需要等待他们可以处理的所有队列(等待其中的任何一个)。

在 Windows 上,我会使用 WaitForMultipleObjects,但这需要是多平台的。

我不想要任何特定的代码,只想要我应该使用的模型的提示或描述。提前致谢。

4

8 回答 8

5

怎么样:

  • 所有工作线程都在一个信号量上等待
  • 当任何东西添加到队列中时,信号量会增加,这会唤醒单个线程
  • 线程检查它感兴趣的队列,处理其中一个并返回等待信号量

您将需要额外的互斥锁来控制对队列的实际读写。

于 2009-05-22T17:19:03.210 回答
4

您可以做的是使用条件变量。让您的工作线程等待条件变量。当作业被添加到任何作业队列时,向条件变量发出信号。然后,当工作线程唤醒时,它会检查它正在等待的队列。如果他们中的任何一个有工作,它就会将该工作从队列中删除。否则,它会返回等待条件变量。等待条件变量会使线程进入睡眠状态,因此它不会消耗 CPU 时间。

当然,不用说您应该使用互斥锁(例如pthread_mutex_t)保护对作业队列的所有访问。

于 2009-05-22T17:03:50.810 回答
1

如果每个队列没有太多工作人员,您可以为每个工作人员创建一个条件变量。

于 2009-05-22T17:03:05.180 回答
0

听起来您应该使用boost::threadboost::conditionstd::queue

于 2009-05-22T17:03:20.950 回答
0

我要做的是使用 boost::asio 对数据进行排队,以便您的多个线程可以使用它。您可以通过 post 命令将 ref 传递给队列,并相应地处理线程。

于 2009-05-22T17:04:19.997 回答
0

与其为每个队列设置一个单独的锁,不如为所有队列设置一个锁?

  1. 等锁
  2. 拿到锁
  3. 从任何队列中出列
  4. 释放锁
  5. 处理出队的项目
  6. 转到第 1 步

假设出队花费的时间可以忽略不计(因此锁只持有可忽略不计的时间),可能不需要多个锁。

于 2009-05-22T17:04:59.577 回答
0

你可以这样做:每个作业都有一个与之关联的“队列”。例如:

假设您有 2 个队列。你的工作可以说:

job[0].queue = 1; /* That job is in queue 1 */
job[1].queue = 1;
job[2].queue = 2; /* this job is in queue 2 */
... 
etc

那么你就有了你的“线袋”。一个线程简单地选择一个工作——比如说,工作[2]。如果只允许该线程处理来自队列 1 的作业,那么它将将该作业放回就绪队列并选择不同的作业。

所以每个线程都知道它允许处理哪些队列,并且当它选择一个作业时,它确保该作业的“队列”字段匹配。如果没有,它会选择不同的工作。

(这在很多方面是进程调度在 linux 上的多核上的工作方式。每个进程都有一个位掩码,说明允许在哪些处理器上运行,然后处理器确保在这样做之前“允许”它运行该进程。 )

于 2009-05-22T17:08:14.283 回答
0

我最近一直在考虑这个问题,我能想到的唯一想法是(假设你有线程安全的队列)只有多个线程服务于一个队列。

然后,您可以让一个或多个工作线程将作业添加到单个队列,并让一个或多个工作线程阻塞队列,直到它们找到要处理的内容。

如果您曾经有多个队列需要多个工作线程轮询,那么解决方案可能是为每个队列添加一个额外的线程和一个额外的队列。额外的线程每个都阻塞在自己的单个队列中,但只是将作业转发到额外的队列。现在,现有的工作线程又回到了阻塞单个队列的状态。

于 2011-06-25T21:40:14.053 回答