最近学习了Grand Central Dispatch,我发现多线程代码非常直观(使用GCD)。我喜欢这样一个事实:不需要锁(事实上它在内部使用无锁数据结构),并且API非常简单。
现在,我开始学习pthreads,我不禁对复杂性感到不知所措。线程连接,互斥体,条件变量 - 所有这些事情在GCD中都不是必需的,但在pthreads中有很多API调用。
pthreads是否比GCD有任何优势?它效率更高吗?是否存在正常使用情况,其中pthread可以执行GCD无法执行的操作(不包括内核级软件)?
在跨平台兼容性方面,我并不太关心。毕竟,libdispatch是开源的,Apple已经将其关闭更改作为GCC的补丁,clang支持关闭,并且已经(e.x.FreeBSD),我们开始看到一些非Apple的GCD实现。我最感兴趣的是使用API(具体的例子会很棒!)。
答案 0 :(得分:15)
我来自另一个方向:在我的应用程序中开始使用pthreads
,我最近用C ++ 11&{39}替换了std::thread
。现在,我正在使用更高级别的构造,如pseudo-boost threadpool,甚至更抽象的英特尔Threading Building Blocks。我认为GCD应该达到甚至高于TBB。
一些评论:
pthreads
或std::thread
这样的线程库。std::thread
等低级库是否有任何好处?答案是响亮的是。使用更高级别库的优点是从实现细节中抽象。使用更高级别库的缺点也是从实现细节中抽象。当使用pthreads
时,我非常了解对象的共享状态和生命周期,因为如果我放松警惕,特别是在中型到大型项目中,我很容易得到竞争条件或内存故障。当我使用更高级别的库时,这些问题会消失吗?并不是的。看起来我不需要考虑它们,但实际上,如果我对这些细节感到邋,那么库的实现也会崩溃。因此,您会发现,如果您了解较低级别的构造,那么所有这些库实际上都是有意义的,因为在某些时候,如果您使用较低级别的调用,您将考虑自己实现它们。当然,在这一点上,使用经过时间考验和调试的库调用通常会更好。所以,让我们分解可能的实现:
pthread
和std::thread
来电:实际上很少有人要求学习,但正确使用它们需要注意细节,并深入了解应用程序的工作原理。如果你能理解这个级别的线程,那么更高级别的库的API肯定会更有意义。哪一个最快?令人惊讶的事实是,它可能是上述三个中的任何一个。要获得多线程的速度优势,您可能需要彻底重新组织算法。这些收益是否超过成本是高度依赖案例的。
哦,OP询问了thread_pool不合适的情况。简单的情况:如果你有一个紧密的循环,每个循环不需要很多循环来计算,使用thread_pool可能比没有严重重做的好处花费更多。还要注意函数调用的开销,比如lambda通过线程池与使用单个紧密循环。
对于大多数应用程序来说,多线程是一种优化,所以在正确的时间和地点进行优化。
答案 1 :(得分:14)
你正在经历的压倒性感觉......这正是GCD被发明的原因。
在最基本的层面上有线程,pthreads是线程的POSIX API,因此您可以在任何兼容的操作系统中编写代码并期望它能够工作。 GCD建立在线程之上(虽然我不确定它们是否真的使用pthread作为API)。我相信GCD只能在OS X和iOS上运行 - 简而言之就是它的主要缺点。
请注意,大量使用线程并需要高性能的项目会实现自己版本的线程池。 GCD允许您无数次地避免(重新)发明轮子。
答案 2 :(得分:4)
GCD是Apple技术,并不是最兼容的跨平台; pthread几乎可以在OSX,Linux,Unix,Windows上使用..包括这个toaster
GCD针对线程池并行性进行了优化。 Pthreads(如你所说)是非常复杂的并行构建块,你可以开发自己的模型。如果您有兴趣了解有关pthreads和不同并行模型的更多信息,我强烈建议您选择一本关于该主题的书。
答案 3 :(得分:3)
任何声明/辅助方法如openmp或Intel TBB GCD都应该非常擅长embarrassingly parallel问题,并且可能很容易击败天真的手动pthread-ed并行排序。我建议你仍然学习pthreads。您将更好地理解并发性,您将能够在每种特定情况下应用正确的工具,如果没有其他任何东西 - 那里有大量基于pthread的代码 - 您将能够读取“遗留”代码。 / p>
答案 4 :(得分:0)
通常:每个Pthread实现1个任务使用互斥锁(操作系统功能)。
GCD:
每个块1个任务,分组为队列。每个虚拟CPU 1个线程可以获得队列,并且在没有互斥锁的情况下运行所有任务。这减少了线程管理开销和互斥开销,这应该会提高性能。
答案 5 :(得分:0)
GCD抽象线程并为您提供调度队列。它在考虑可用处理器核心数量的情况下创建必要的线程。 GCD是开源的,可通过libdispatch库获得。 FreeBSD自8.1起包含libdispatch。 GCD和C Blocks是Apple向C编程社区提供的市长贡献。我永远不会使用任何不支持GCD的操作系统。