代码之家  ›  专栏  ›  技术社区  ›  Mike

pthreads比GCD有什么优势吗?

  •  19
  • Mike  · 技术社区  · 15 年前

    在最近学习了GrandCentralDispatch之后,我发现多线程代码非常直观(使用GCD)。我喜欢这样一个事实:不需要锁(而且它在内部使用无锁数据结构),而且API非常简单。

    现在,我开始学习pthreads了,我忍不住被它的复杂性弄得有点不知所措。线程连接、互斥、条件变量——所有这些在GCD中都不是必需的,但是在pthreads中有很多API调用。

    pthreads比GCD有什么优势吗?它更有效吗?pthreads可以做GCD不能做的事情(不包括内核级软件)是否有正常的用例?

    在跨平台兼容性方面,我不太担心。毕竟,libdispatch是开源的,苹果已经将其关闭更改淹没在gcc的补丁中,clang支持关闭,而且(e.x.freebsd)我们已经开始看到一些非苹果的gcd实现。我最感兴趣的是API的使用(具体的例子会很棒!).

    6 回复  |  直到 11 年前
        1
  •  14
  •   Constantino Tsarouhas    12 年前

    你正在经历的那种压倒性的感觉……这就是为什么发明了GCD。

    在最基本的级别上,有线程,pthreads是线程的posix API,因此您可以在任何兼容的操作系统中编写代码,并期望它能够工作。GCD构建在线程之上(尽管我不确定它们是否真的使用pthreads作为API)。我相信GCD只适用于OS X和iOS,简而言之,这是它的主要缺点。

    请注意,大量使用线程并需要高性能的项目实现了自己的线程池版本。GCD允许你避免(重新)发明轮子无数次。

        2
  •  15
  •   kfmfe04    13 年前

    我来自另一个方向:开始使用 pthreads 在我的应用程序中,我最近用C++ 11替换了它。 std::thread . 现在,我在玩像 pseudo-boost threadpool 更抽象的是,英特尔的 Threading Building Blocks . 我认为GCD达到或甚至高于TBB。

    一些评论:

    • 伊莫,pthread是 不太复杂 比起GCD:在其基本核心,pthread实际上只包含很少的命令(只有一小部分:仅使用OP中提到的命令,您就可以获得95%以上的所需功能)。像任何较低级别的库一样,它是如何将它们组合在一起以及如何使用它们,从而赋予您强大的功能。不要忘记,像gcd和tbb这样的库最终会调用线程库 线程 STD::线程 .
    • 有时候,不是 你用什么,但你怎么用 决定成败。作为图书馆的支持者,tbb或gcd会告诉你使用他们图书馆的所有好处,但是在你在真实的应用环境中尝试之前,所有这些都是 理论效益 . 例如,当我读到使用 细颗粒平行 我立即将其用于我认为可以从并行性中获益的任务。当然,我也被这样一个事实所吸引:tbb将处理关于最佳负载平衡和线程分配的所有细节。结果如何? tbb比单线程版本长5倍! 但我并不责怪tbb:回想起来,这显然是一个误用parallel的案例,因为:当我阅读这篇文章时,我发现了使用parallel-for的开销,并假设在我的案例中,上下文切换和添加函数调用的成本超过了使用多线程的好处。所以你必须分析一下你的案例,看看哪个会跑得更快。您可能需要重新组织算法以减少线程开销。
    • 为什么会这样?pthread或no线程如何比gcd或tbb更快?设计师设计GCD或TBB时,必须 做出假设 关于运行任务的环境。事实上,库必须足够通用,以便开发人员能够处理奇怪的、不可见的用例。这些一般的实现不会是免费的。另一方面,库将查询硬件和当前运行环境,以更好地实现负载平衡。对你有好处吗?唯一的办法就是试试看。
    • 学习低级图书馆有什么好处吗? STD::线程 何时有更高级别的库可用?答案是 响亮的是 .使用高级库的好处是, 从实现细节中提取 . 这个 缺点 使用更高级别的库也是 从实现细节中提取 . 使用时 线程 ,我非常清楚对象的共享状态和生命周期,因为如果我放松警惕,特别是在大中型项目中,我可以很容易地 竟态条件 内存故障 . 当我使用更高级别的库时,这些问题会消失吗?不是真的。似乎我不需要考虑它们,但实际上,如果我对这些细节草率处理,库实现也会崩溃。因此,您会发现,如果您了解较低级别的结构,那么所有这些库实际上都是有意义的,因为在某些时候,如果您使用较低级别的调用,那么您将考虑自己实现它们。当然,在这一点上,最好使用经过时间测试和调试的库调用。

    那么,让我们来分解可能的实现:

    • TBB/GCD 库调用:对线程初学者来说,最大的好处是。与学习较低水平的图书馆相比,他们的入学门槛更低。但是,它们也忽略/隐藏使用多线程的一些陷阱。动态负载平衡将使您的应用程序更具可移植性,而无需编写额外的代码。
    • pthread STD::线程 调用:实际上要学习的调用很少,但是正确使用它们需要注意应用程序如何工作的细节和深层意识。如果您能够理解这个级别的线程,那么更高级别库的API当然会更有意义。
    • 单线程算法 :让我们不要忘记简单的单线程段的好处。对于大多数应用程序,单线程比多线程更容易理解,并且更不容易出错。实际上,在许多情况下,它可能是合适的设计选择。事实上,一个真正的应用程序经历了不同的多线程阶段和单线程阶段:可能不需要一直都是多线程的。

    哪一个最快? 令人惊讶的是,这可能是上述三种情况中的任何一种。为了获得多线程的速度优势,您可能需要彻底重新组织算法。利益是否大于成本取决于具体情况。

    哦,OP询问了线程池不合适的情况。简单的例子:如果您有一个紧密的循环,不需要每个循环计算很多个循环,那么使用线程池的成本可能会比不进行严重返工的好处要高。还要注意通过线程池进行lambda等函数调用与使用单个紧密循环的开销。

    对于大多数应用程序,多线程是一种优化,因此在正确的时间和位置进行优化。

        3
  •  4
  •   Chris S    15 年前

    GCD是一种苹果技术,不是最兼容跨平台的;pthread几乎可以在OSX、Linux、Unix、Windows的所有产品上使用。包括这个 toaster

    GCD针对线程池并行性进行了优化。pthreads是(如您所说)非常复杂的并行构建块,您可以自行开发模型。如果你想了解更多关于pthreads和不同的并行模型的知识,我强烈建议你读一本关于这个主题的书。

        4
  •  3
  •   Nikolai Fetissov    15 年前

    如任何声明性/辅助方法 openmp Intel TBB GCD应该非常擅长 embarrassingly parallel 有问题,很可能会轻易击败na195’ve手动pthread ed parallel sort。不过,我建议你还是学习pthreads。您将更好地理解并发性,您将能够在每个特定的情况下应用正确的工具,而且如果没有其他任何原因(外面有大量基于pthread的代码),您将能够读取“遗留”代码。

        5
  •  0
  •   Andy Jackson    14 年前

    通常:每个pthread实现一个任务使用互斥锁(操作系统功能)。
    GCD: 每个块1个任务,分组成队列。每个虚拟CPU有一个线程可以获得一个队列,并在所有任务中不使用互斥体运行。这样可以减少线程管理开销和互斥量开销,从而提高性能。

        6
  •  0
  •   ColemanCDA    11 年前

    GCD提取线程并给您分派队列。它根据需要创建线程,同时考虑可用处理器核心的数量。 GCD是开放源码的,可以通过libdispatch库获得。FreeBSD包括8.1版的libDispatch。GCD和C块是苹果公司对C编程社区的主要贡献。我绝不会使用任何不支持GCD的操作系统。