为什么要知道并发编程?


17

并发编程对我来说相当困难:即使看一张基本幻灯片对我来说也充满挑战。看来太抽象了。

很好地了解并发编程概念有什么好处?它对定期进行顺序编程有帮助吗?我知道了解我们的程序如何工作很满意,但是还有什么呢?


3
我认为这有点不适应主题,但是如果您编辑掉所有个人内容(尽管并发编程对每个人来说都是相当困难的)并要求概念的具体技术优点,那么它就可以使您陷入困境。
yannis 2011年

1
好处应该很明显。您可以编写程序,这些程序可以通过并发编程提供的分工来利用所有可用的性能增强。对任何人来说都不容易。今天,这是一个非常具有挑战性的概念。
钻机

3
我们不能帮助您获得学习知识的动力,但是有关为什么应该了解并发性的一般问题已经足够了。

2
我知道并发编程。我可以告诉您,您提供的幻灯片不会帮助您理解。取而代之的是和餐饮哲学家一起去参加聚会。
mouviciel 2011年

1
放松,即使最伟大的人也感到困难:informit.com/articles/article.aspx?p = 1193856
SK-logic

Answers:


32

这是一个快速简便的动机:如果您想为最小,最弱的系统之外的任何事物编写代码,那么您在编写并发代码。

想为云写东西吗?云中的计算实例很小。你没有大的,你有很多的小。突然,您的小型Web应用程序是并发应用程序。如果设计得当,您可以在赢得客户时投入更多服务器。否则,您必须了解实例固定其平均负载的方式。

确定,您要编写桌面应用程序吗?一切都有双核或更多核CPU。除了最便宜的机器。而且拥有最便宜机器的人可能不会为您的昂贵软件买单,是吗?

也许您想进行移动开发?嘿,iPhone 4S具有双核CPU。其余的将不会落后。

视频游戏?Xbox 360是一个多CPU系统,索尼的PS3本质上是一个多核系统。

除非您正在处理微小的简单问题,否则您就无法摆脱并发编程。

2016年更新:35美元的Raspberry Pi的当前版本基于用于手机的芯片上的四核系统构建。人工智能的巨大进步部分归功于高端图形卡作为并行计算引擎的可用性。


1
虽然我原则上同意,但是这Everything has a dual-or-more-core-CPU. Except the least expensive machines.听起来有些荒谬。很多人拥有单核计算机,不是因为它便宜,而是因为他们对已有的设备感到满意,并且不需要升级。也就是说,在并发方面进行思考也将有助于单核系统上的调度程序,因此,在任何可以采用抢占式多任务处理的地方(这都是大多数开发人员都会接触的每一个多任务环境,这些日子)​​。
的CVn

1
好的-有点夸张,但是新硬件绝大多数都是多核的。我看不到那消失。因此,如果您今天是一名学生,正在考虑您将来将要从事的专业工作,那么可以肯定地假设您将在多核系统上工作。
ObscureRobot 2011年

我想知道我是否与您不同意我的回答一样多;)

1
以我的阅读方式来说,@ acidzombie24与我们俩都说的有相似之处。我是说开发人员应该知道如何处理并发,因为并发无处不在。您说的是只要您避免并发系统的陷阱就不必擅长并发编程:)
ObscureRobot 2011年

我同意了解并发非常有用,但是不同意您只能因为“微小的简单问题”而无法使用并发。即使在非平凡的系统中,例如在您依赖现有框架和应用程序服务器的情况下,您也可以避免并发。基础架构到位后,我可以成为初级开发人员,为Web应用程序编写新服务,并且几乎不了解并发或并行性。
Andres F.

21

从1970年到2002年左右,处理器的速度大约每18个月翻一番。因此,作为一名程序员,您要做的就是等待,然后您的程序运行得更快。问题在于,大约在2002年,规则发生了变化。现在,他们不是在制造更大的快速处理器,而是在制造更小的慢速处理器,而是将它们按组推出。我正在使用的计算机现在有4个内核,并且存在最多具有8个内核(每个内核有4个线程)的芯片。很快,我们将拥有更多内核的芯片。

因此,如果您编写的程序完全不是并行的,则会发现您使用的是1个内核或线程,而其余的CPU却坐在那里什么也不做。因此,如果您有16个核心,则1将运行您的程序,而其他15个则坐在那里!

并发的问题在于它是不确定的。就是说,您不确切知道不同线程将按什么顺序执行操作。传统上,程序员尝试使用锁等来解决此问题。这导致了很多痛苦。具有某种形式的可变状态,多个线程可以自由访问,这通常是痛苦和冒犯的公式!

最近的趋势是转向紧密控制可变状态的功能语言。功能语言处理并发有两种基本方法。第一种是通过使用消息传递。Erlang最好地显示了这一点。在Erlang中,进程之间通常没有共享状态。他们交流不是通过共享内存,而是通过我传递的消息。我们目前正在这样做,这对您来说应该很有意义。我是通过向您发送一条消息来向您发送此信息,而不是让您从我的脑海中记住它!通过切换到消息传递,大多数锁定错误都将消失。另外,消息可以通过网络以及在一个节点内传递。

另一种方法是STM,代表软件转录记忆,它存在于clojure和Haskell(及其他)中。在STM中,内存是共享的,但只能通过事务进行更改。正如数据库人员在1970年代发现的所有这些东西一样,很容易确保我们做对了。

实际上,我稍微简化了一点,Clojure和Haskell都可以进行消息传递,而Erlang可以进行STM。

免责声明我是《用Erlang编程Web服务》的作者,它将在接下来的几周内于早期版本中发布。


1
@Zachary K:是否有将功能语言与本机语言混合在一起的方法,以便以本机语言实现计算密集型部件,但它们提供了可以由用功能语言编写的服务器使用的接口?
rwong 2011年

不能100%确定,但是Clojure和Scala都存在于JVM上,所以这就是我的起点。也许看看Akka框架。我没有使用过它,但是前一段时间确实听了关于Akka的谈话,看来它可能很酷。现在,我正在使用Erlang和Javascript,这占用了我的大部分时间!
Zachary K,

1
@rwong:.NET允许程序员将C#或其他非功能性语言用于其应用程序的某些部分,并将F#(一种功能性语言)用于其他应用程序。
凯文

5

因为并发可能在您最不希望的时候突然出现在您的面前...


4
+10000000000000000000000000000000000000000000000

8
并发是新的西班牙裁判所[/ python] [如:没有人期望...]
ObscureRobot 2011年

1
@ObscureRobot两倍有趣!(不需要解释:-p)
fortran

4

并发编程的第一条规则是“很难”。并发编程的第二条规则是“很难。”。

严肃地说,并发编程有两种通用方法,即多线程和多处理。多处理是最容易理解的,因为它只是意味着要运行一个流程的多个实例来完成一项任务。在基于Unix的系统上,通过调用fork / join相当容易,但是在Windows系统上却不那么容易。

多线程可能是大多数人在谈论并发时想到的方法。在一个应用程序中启动多个线程并不难,但细节在于魔鬼。您需要协调线程之间的数据共享(通常使用锁),这可能导致死锁或数据处于无效状态。您还需要了解如何使用信号量,条件变量等概念在线程之间进行通信。

所有这些的好处是,一旦您了解了它,便能够更有效地利用基础硬件。如今,处理器具有多个内核已成为几乎正常的情况。通过利用并发编程,您可以使这些内核为您工作,并且您的应用程序将获得更快的速度。

缺点是您必须开始考虑如何将应用程序拆分为可以在不同线程上运行的小部分。这比听起来要难得多。另外,由于执行顺序的确定性较差,因此高度并行的解决方案可能难以进行单元测试。

如今,大多数语言都对大多数并发原语进行了抽象,以使生活变得更轻松。例如,.NET 4随任务并行库一起提供,这使工作变得更轻松。在Java领域,他们拥有并发包


1
如果您尽可能快地摆脱锁,它将达到几个数量级。使用STM或actor,您所说的所有内容都会消失。当然,这意味着要从Java转向诸如Scala,Erlang或Clojure之类的语言。(尽管我会认为这也是一件好事)
Zachary K

@Zachary:这可能是一件好事,但是例如,如果您在.NET商店中工作,那是不切实际的。STM可能会在将来成为一个选择,但现在它不是主流语言中的一个选择。
肖恩

Clojure在.net上运行,并且有F#。我敢打赌,还有C#的STM实现。
Zachary K,

3

最近,我完成了一项非常有趣的任务,其中多处理可以帮助我。基本上,我不得不对几个单独的服务器执行很多请求,处理的数据量非常小,但是请求很多。

使用PHP,我以老式的方式进行操作,经过几个小时的工作,我获得的最佳时间导致大约120秒的时间来运行某个测试(许多请求+网络延迟+无异步)

但这与我所需的资源相比还远远不够,在PHP的多处理失败后,我转向了Python。

几个小时后,我有了一个正在运行的Python多处理脚本,该脚本在20秒内运行,并且对超时有些不满意,然后又没有了。所使用的线程数,我将其降低到约10秒

这是针对100%用PHP编写的网站,除了一个100行的Python脚本外。整个过程运行完美。

我的结论是,即使它无法每天为您提供帮助,您也可能会遇到这样的情况,至少了解并发编程的基础知识会极大地帮助您。

祝您好运,编码愉快!

PS:我并不是想抨击PHP,但是PHP根本不是适合当前工作的正确工具。

PS2:了解新技术或新的做事方式可以打开通往可能性新世界的大门。


2

如果您进行任何类型的Web开发,则并发至少在大多数语言中都起作用。例如,我将spring用于Web开发,每个新请求都作为其自己的线程进入。因此,如果任何请求最终访问了一个共享对象,而在该对象中可以更改变量的状态,则并发是一个非常重要的因素,必须加以考虑。如果不是这样,则可以以不可预测的方式编辑数据,并且可能导致数据损坏。了解并发的每一个最后细节并不重要,但是一次学习部分对于更好地了解Web应用程序编程很重要,如果您正在使用桌面应用程序,那么除非您需要运行多个线程,否则它并不那么重要。


-1

了解操作系统的见解。阅读调度程序和设备驱动程序的源代码将有所帮助;他们肯定是并发的。


2
程序员的并发通常用于在多个实例中运行的您自己的程序。

我试图强调,无论如何,如果不知道OS内核的调度算法的细节,就无法编写自己的并发程序。
jj1bdx

为什么不?如果正确使用锁定机制,则操作系统调度算法不重要。
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.