【问题标题】:Multithreading to perform a single task in C++多线程在 C++ 中执行单个任务
【发布时间】:2016-02-21 06:42:06
【问题描述】:

假设我有这个 big_task() 函数,我可以在线程之间拆分以加快速度。

解决多线程问题的方法是在函数的每个任务上调用_beginthread(),然后等待所有线程完成,对吧?

我如何知道这是否会有效并真正有益于最大限度地减少 big_task() 运行时间?

我还听说多线程效率取决于客户端的平台和硬件。这意味着我也需要在程序开始时查询它..?

还有一个问题,在 Windows 中编码时,使用CreateThread() 比使用_beginthread() 更好吗?我编写跨平台应用程序,但如果 CreateThread() 比我可以专门编写代码以在 Windows 中使用它更有效。

【问题讨论】:

  • 你能解释一下任务的类型吗? (网络、数据库访问、磁盘 io、cpu 时间?)
  • 如果您使用的是 C++11,我相信您可以改用 std::thread。
  • 首先,如果你在多处理器/多核系统上,当然多线程会更快。
  • @AlexandreLavoie:仅当这些任务可以并行执行时;-)
  • @Pilpel 如果您满意,您应该接受其中一个答案。它不需要是我的答案;-)

标签: c++ multithreading


【解决方案1】:

我希望这将帮助您开始。

要实现单线程方法的加速,您需要多核 CPU。在单核 CPU 上,额外线程不会提高计算速度,但它可能有助于在执行 CPU 密集型工作的同时使其他功能(例如 GUI)顺利运行。

要利用多核 CPU,您需要将“大任务”拆分成可以同时执行且互不影响的块。

一般流程:

  1. 将块放入容器中。将其状态设置为“可用”。
  2. 根据需要创建尽可能多的线程(实际 CPU 核心数最多为 有用)。
  3. 这是线程函数。它们是并行执行的。

    1. 尝试从 容器并使其“忙碌”。如果没有找到“可用”块,则退出线程。
    2. 处理块并使其“就绪”。
    3. 返回 (4)
  4. 在主线程中等待所有工作线程完成。您可能会在循环中等待每一步休眠一秒钟,检查是否按下了 Ctrl-C。或者干脆在所有线程上“加入”(等到线程退出)。

  5. 将所有块收集在一起并使用您的计算结果。

请注意,您需要注意访问相同数据的多个线程,因为它们可能会相互干扰。例如,多个线程有可能在同一时间获取相同的块进行处理。 这个问题可以用互斥锁解决(见boost::mutex)。

还有其他方法可以解决这个问题。您可以将块放入消息队列 (FIFO) 中,然后让线程将它们从队列中弹出并将结果放入其他队列中。如果您通过网络扩展此队列,您可以使用多台 PC 来完成这项工作。

为了便于携带,您可以使用boost::thread。

这也很有用:boost::thread_group

【讨论】:

    【解决方案2】:

    解决多线程问题的方法是在函数的每个任务上调用_beginthread(),然后等待所有线程完成,对吗?

    这样你将并行化你的大函数,所以是的,那是真的。

    我怎么知道这是否会有效并真正有利于最大限度地减少 big_task() 运行时间?

    您必须对其进行概要分析。如果您的大函数在 CPU 上执行代码,没有 I/O 操作,那么请考虑创建与 CPU 中的内核数相同的线程数。

    我还听说多线程效率取决于客户端的平台和硬件。这意味着我也需要在程序开始时查询它..?

    具有更多内核的 CPU 肯定会比具有更少内核的 CPU 更快,您可以查看 PPL(仅限 win)、TBB、OpenMP 库,这些库可确保基于 CPU 内核数量有效运行任务。

    还有一个问题,在 Windows 中编码时,使用 CreateThread() 比使用 _beginthread() 更好吗?我编写跨平台应用程序,但如果 CreateThread() 比我专门编写的代码在 Windows 中使用它更有效。

    如果您想要跨平台,请使用 std::thread 或 boost。

    【讨论】:

    • @Pilpel 因为它只有 windows 的功能,在 linux 下等效的是 pthreads 库。 std::thread 将适用于 Windows、Linux、...
    • @Pilpel 不,它不是 - 它只是不跨平台。有关 CreateThread 和 _beginthreadex 之间的差异,请阅读此处:stackoverflow.com/questions/331536/…。
    • 我明白了。最后一个要确定的问题:C++11 代码可以在 C++03 运行的任何平台上运行,对吧?
    • @Pilpel 是的,您只需要一个与该平台兼容的 c++11 编译器。
    • Boost 很方便,因为它是多平台的。您可以为 Linux 和 Windows 构建 boost 库。如果您喜欢,您可以在 Qt Creator 中拥有相同的项目(项目文件中的开关很少),它将在多个平台上编译和调试。 boost 中有更多有用的东西,比如 shared_ptr 和 asio。当然 shared_ptr 现在在 C++11 中可用。
    猜你喜欢
    • 2018-10-07
    • 2017-06-16
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多