【问题标题】:Multi-threading jobs that need to maintain order需要维护秩序的多线程作业
【发布时间】:2011-06-18 21:16:23
【问题描述】:

我有一个 c/c++ 进程,它有一个很长的队列,这个队列中的每个元素都需要 发送到多个(TCP)服务器。单线程是一个可行的选项,但它很慢。

我需要实现一个多线程解决方案。我的进程事先不知道编号 服务器。第一个想法是为每个服务器创建一个线程。管理器线程读取 队列中的新元素找到目的地并分派到与目的地匹配的线程。

一个重要的注意事项。工作可能是依赖的。如果job_5没有完成,我不想执行job_10。需要维持秩序。

首先,我想听听您对这个问题的看法。其次,我正在寻找 C++ 实现以供参考。第三,我正在寻找描述类似问题的书籍/资料。

【问题讨论】:

  • 你是什么意思?用于新连接的分叉?
  • 这个问题的真正解决方案是Asynchronous IO
  • 我建议查找线程池。 “多线程”的概念通常被认为是每个客户端线程。线程池是一种有效的方式来摆脱你可能并不总是需要的线程。
  • @RageD:我认为在这种情况下线程池是一个实现细节。它确实与性能有关,这是最初的动机,但我认为我们仍处于设计阶段,可以公平地假设池实现相对可插入。

标签: c++ c multithreading pthreads threadpool


【解决方案1】:

你看过boost asio吗?它支持“线程池”的概念,因此您可以使用一个线程池异步处理大量连接,而不是每个服务器一个线程(即同步)。性能也不错...

【讨论】:

  • 相同。救了我添加答案。线程创建相当繁重,所以最好不要结束它们,只是为了在下一个请求到来时启动另一个线程。
  • 问题是我还需要维护秩序。例如 job_1 goues to thread_1 并且需要完成才能将 job_2 发送到同一个连接。
  • 根据队列中对象的重量,您可以不为每个连接维护一个队列吗?然后线程所要做的就是将一个项目从给定队列分派到给定目的地,然后处理下一个项目。发送到给定目的地的项目的顺序由队列维护......
  • 或者,存储队列中给定项目应分派到的连接集,并在项目发送到每个连接时清除此集。一旦集合为空,就可以从队列中删除该项目...无论如何,有多种方法可以解决该问题...
【解决方案2】:

您是如何得出需要多线程解决方案的结论的?当您说您的单线程解决方案“慢”时,您是什么意思?您的意思是在将项目发送到服务器时会阻止其他处理(可能是 UI 的东西?)?还是整个过程耗时太长?

您对这个问题的描述含糊不清:每个项目都需要发送到所有服务器,还是只发送到一个服务器?好像只有一个,但我不确定。如果一定要发送给所有人,那么多线程解决方案的复杂性会大大增加。

您是否可以在发送项目后从队列中删除它,或者您是否需要等待服务器的确认?如果您必须等待,那么您的队列管理将变得棘手 - 在项目被确认之前您无法删除该项目,因此您必须以某种方式将其标记为待处理,并且从队列中选择下一个项目的线程将需要以确保它不会选择待处理的项目。当项目成功发送后,它必须从队列中移除,这意味着对队列的并发写访问。

您如何处理错误?如果一个项目无法发送,它会留在队列中以供以后重试,还是移动到失败列表中,还是只是记录并丢弃?在多线程系统中,您将异步了解故障,这意味着对错误处理过程的并发写访问。

你说你的进程事先并不知道有多少台服务器。这个数字在处理过程中可以改变吗?

无论如何都要研究多线程,但您可能会发现“慢速”单线程解决方案最能满足您的业务需求 - 易于实施且可靠。如果没有,那么希望其中一些问题对您有所帮助。

【讨论】:

  • 每个项目都需要发送到一个服务器,我需要等待 ACK。错误案例只是被记录和丢弃。客户端永远不会事先知道服务器的数量。单线程可能很慢,因为存在大量 tcp 超时。例如,有时我们需要等待 10 秒...
  • 将每个项目只发送到一个服务器,并等待 ACK:Nim 的建议听起来很合适。您还提到了保持物品有序 - 大概这意味着在指定服务器的物品中进行订购,而不是在所有物品中订购而不考虑服务器?
猜你喜欢
  • 2015-10-28
  • 2021-07-19
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2011-08-08
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多