多核和并发-语言,库和开发技术
CPU体系结构格局已发生变化,多核技术已成为一种趋势,它将改变我们开发软件的方式。我已经用C,C ++和Java完成了多线程开发,并且已经使用各种IPC机制完成了多进程开发。对于开发人员来说,使用线程的传统方法似乎并不容易使它能够使用支持高度并发性的硬件。
我们知道哪些语言,库和开发技术可帮助减轻创建并发应用程序的传统挑战?我显然在考虑诸如僵局和比赛条件之类的问题。设计技术,库,工具等也很有趣,它们可以帮助实际利用并确保仅在编写安全,可靠的线程化应用程序时利用可用资源,而不能确保其在使用所有可用内核。
到目前为止,我所看到的是:
- Erlang:基于流程的消息传递IPC,"参与者的并发模型"
- Dramatis:针对Ruby和Python的actors模型库
- Scala:JVM的功能性编程语言,并添加了一些并发支持
- Clojure:具有actors库的JVM的功能性编程语言
- 白蚁:Erlang的处理方法和消息传递到Scheme的端口
我们还知道什么,什么对我们有用,并且我们认为值得关注的是什么?
解决方案
我们提到了Java,但只提到了线程。我们是否看过Java的并发库?它与Java 5及更高版本捆绑在一起。
这是一个非常不错的库,其中包含ThreadPools,CopyOnWriteCollections等。在Java教程中查阅文档。或者,如果我们愿意,可以使用Java文档。
我知道Reia是一种基于Erlang的语言,但看起来更像Python / Ruby。
我一直在密切关注.NET和Parallel LINQ的Parallel Extensions。
我已经将处理用于Python。它模仿了线程模块的API,因此非常易于使用。
如果碰巧使用map / imap
或者生成器/列表理解,将代码转换为使用`processing'很简单:
def do_something(x): return x**(x*x) results = [do_something(n) for n in range(10000)]
可以与
import processing pool = processing.Pool(processing.cpuCount()) results = pool.map(do_something, range(10000))
它将使用许多处理器来计算结果。也有惰性(Pool.imap
)和异步变量(Pool.map_async
)。
有一个实现Queue.Queue
的队列类,和类似于线程的工作器。
陷阱
"处理"基于"叉()",它必须在Windows上进行仿真。对象是通过pickle
/unpickle
传输的,因此我们必须确保此操作有效。分叉已经获得资源的进程可能不是我们想要的(考虑数据库连接),但是总的来说它可以工作。它运行得很好,以至于它已被快速添加到Python 2.6中(参见PEP-317)。
英特尔的C ++线程构建模块对我来说非常有趣。它提供了比原始线程更高的抽象级别。如果我们喜欢死树文档,那么O'Reilly的书非常不错。另请参阅"英特尔线程构建模块的任何经验?"。
这个问题与(如果不是重复的话)紧密相关,我们今天建议使用哪种并行编程模型来利用明天的多核处理器?
我会说:
模型:线程+共享状态,参与者+消息传递,事务性内存,映射/减少?
语言:Erlang,Io,Scala,Clojure,Reia
库:Retlang,Jetlang,Kilim,Cilk ++,fork / join,MPI,Kamaliaa,Terracotta
我维护一个有关此类东西(Erlang,Scala,Java线程,actor模型等)的并发链接博客,并且每天建立几个链接:
http://concurrency.tumblr.com
我建议进行两次范式转换:
我们可能需要看一下软件事务存储(STM)的概念。这个想法是使用乐观并发:任何与其他并行运行的操作都试图在一个隔离的事务中完成其工作;如果在某个时候提交了另一个事务,该事务使该事务正在运行的数据无效,则该事务的工作将被丢弃,并且该事务将再次运行。
我认为,该想法的第一个广为人知的实现(如果不是概念证明,也是第一个)是Haskell中的实现:Haskell中有关事务存储的论文和演示。 Wikipedia的STM文章中列出了许多其他实现。
处理并发的另一种非常不同的方法是在E编程语言中实现。
请注意,它处理并发以及语言设计其他部分的方式很大程度上基于Actor模型。
问题我们今天建议使用哪种并行编程模型来利用明天的多核处理器?已经被问到了。我也在那里给出了以下答案。
Kamaelia是一个python框架,用于构建具有许多通信流程的应用程序。
http://www.kamaelia.org/cat-trans-medium.png Kamaelia - Concurrency made useful, fun In Kamaelia you build systems from simple components that talk to each other. This speeds development, massively aids maintenance and also means you build naturally concurrent software. It's intended to be accessible by any developer, including novices. It also makes it fun :) What sort of systems? Network servers, clients, desktop applications, pygame based games, transcode systems and pipelines, digital TV systems, spam eradicators, teaching tools, and a fair amount more :)
这是Pycon 2009的视频。首先将Kamaelia与Twisted和Parallel Python进行比较,然后进行Kamaelia的演示。
与Kamaelia第1部分轻松并发(59:08)
与Kamaelia的第2部分轻松并发(18:15)
我们也知道Java有一个actors库。我们知道Java是一种功能语言吗? ;)
一些基于Scala的东西:
- PiLib:Pi演算风格并发的托管语言
- 基于事件的编程,无需反转控制
- 统一线程和事件的参与者
- Scala组播演员:体系结构和实现
- 使用可扩展模式匹配实现联接
- 交流Scala对象(修订版)
OpenMP。
它为我们处理线程,因此我们只需要担心要并行运行C ++应用程序的哪些部分。
例如。
#pragma omp parallel for for (int i=0; i < SIZE; i++) { // do something with an element }
上面的代码将在我们告知openmp运行时使用的线程数上运行for循环,因此,如果SIZE为100,并且我们具有四核框,则for循环将在每个内核上运行25个项目。
对于各种语言,还有其他一些并行扩展,但是我最感兴趣的是在图形卡上运行的扩展。那才是真正的并行处理:)(示例:GPU ++和libSh)
C ++ 0x将提供std :: lock
函数,用于将多个互斥体锁定在一起。这将有助于减轻由于乱序锁定而引起的死锁。同样,C ++ 0x线程库将具有promise,future和打包任务,这使线程可以等待在另一个线程上执行的操作的结果,而无需任何用户级锁定。
我从.Net并行扩展开始。但是,它是一个CTP,并且在每个新的实现中都在变化。现在,我将C与ThreadPool,BackgroundWorker和Thread实例一起使用。我正在中型应用程序中重新编码一些关键过程。
我不知道从哪里开始。但是,我购买了Gaston C. Hillar Packt Publishing http://www.packtpub.com/beginners-guide-for-C-sharp-2008-和" C2008和2005线程编程"这本书的电子书版本。 -2005-threaded-programming / book,7天前。我从出版商那里购买了电子书,但是现在可以在Amazon.com上找到该书。
强烈建议程序员使用。
我下载了代码,然后开始进行练习。这本书是一本不错的指南,其中包含许多要练习的代码。我阅读了前6章。它在讲故事的同时解释了最困难的概念。那挺好的。很高兴阅读。我可以看到我的Core 2 Quad Q6700在Cusing 4个并发线程中达到了98%的CPU使用率编程!比我想的要容易。我们可以同时使用多个内核而获得的结果给我留下了深刻的印象。我向有兴趣使用C#进行多核或者线程编程的人推荐这本书。
我已经在Ada中进行并发编程近20年了。
语言本身(没有在库中添加某些语言)支持线程("任务"),多个调度模型和多个同步范例。我们甚至可以使用内置原语来构建自己的同步方案。
我们可以将Ada的集合点视为一种面向过程的同步工具,而受保护的对象则更加面向对象。集合点类似于监视器的旧CS概念,但功能强大得多。受保护的对象是具有同步原语的特殊类型,可让我们构建与操作系统锁,信号灯,事件等完全相同的内容。但是,它的功能非常强大,我们还可以根据自己的实际需要发明和创建自己的同步对象。