并发编程对我来说相当困难:即使看一张基本幻灯片对我来说也充满挑战。看来太抽象了。
很好地了解并发编程概念有什么好处?它对定期进行顺序编程有帮助吗?我知道了解我们的程序如何工作很满意,但是还有什么呢?
并发编程对我来说相当困难:即使看一张基本幻灯片对我来说也充满挑战。看来太抽象了。
很好地了解并发编程概念有什么好处?它对定期进行顺序编程有帮助吗?我知道了解我们的程序如何工作很满意,但是还有什么呢?
Answers:
这是一个快速简便的动机:如果您想为最小,最弱的系统之外的任何事物编写代码,那么您将在编写并发代码。
想为云写东西吗?云中的计算实例很小。你没有大的,你有很多的小。突然,您的小型Web应用程序是并发应用程序。如果设计得当,您可以在赢得客户时投入更多服务器。否则,您必须了解实例固定其平均负载的方式。
确定,您要编写桌面应用程序吗?一切都有双核或更多核CPU。除了最便宜的机器。而且拥有最便宜机器的人可能不会为您的昂贵软件买单,是吗?
也许您想进行移动开发?嘿,iPhone 4S具有双核CPU。其余的将不会落后。
视频游戏?Xbox 360是一个多CPU系统,索尼的PS3本质上是一个多核系统。
除非您正在处理微小的简单问题,否则您就无法摆脱并发编程。
2016年更新:35美元的Raspberry Pi的当前版本基于用于手机的芯片上的四核系统构建。人工智能的巨大进步部分归功于高端图形卡作为并行计算引擎的可用性。
Everything has a dual-or-more-core-CPU. Except the least expensive machines.
听起来有些荒谬。很多人拥有单核计算机,不是因为它便宜,而是因为他们对已有的设备感到满意,并且不需要升级。也就是说,在并发方面进行思考也将有助于单核系统上的调度程序,因此,在任何可以采用抢占式多任务处理的地方(这都是大多数开发人员都会接触的每一个多任务环境,这些日子)。
从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服务》的作者,它将在接下来的几周内于早期版本中发布。
因为并发可能在您最不希望的时候突然出现在您的面前...
并发编程的第一条规则是“很难”。并发编程的第二条规则是“很难。”。
严肃地说,并发编程有两种通用方法,即多线程和多处理。多处理是最容易理解的,因为它只是意味着要运行一个流程的多个实例来完成一项任务。在基于Unix的系统上,通过调用fork / join相当容易,但是在Windows系统上却不那么容易。
多线程可能是大多数人在谈论并发时想到的方法。在一个应用程序中启动多个线程并不难,但细节在于魔鬼。您需要协调线程之间的数据共享(通常使用锁),这可能导致死锁或数据处于无效状态。您还需要了解如何使用信号量,条件变量等概念在线程之间进行通信。
所有这些的好处是,一旦您了解了它,便能够更有效地利用基础硬件。如今,处理器具有多个内核已成为几乎正常的情况。通过利用并发编程,您可以使这些内核为您工作,并且您的应用程序将获得更快的速度。
缺点是您必须开始考虑如何将应用程序拆分为可以在不同线程上运行的小部分。这比听起来要难得多。另外,由于执行顺序的确定性较差,因此高度并行的解决方案可能难以进行单元测试。
如今,大多数语言都对大多数并发原语进行了抽象,以使生活变得更轻松。例如,.NET 4随任务并行库一起提供,这使工作变得更轻松。在Java领域,他们拥有并发包。
最近,我完成了一项非常有趣的任务,其中多处理可以帮助我。基本上,我不得不对几个单独的服务器执行很多请求,处理的数据量非常小,但是请求很多。
使用PHP,我以老式的方式进行操作,经过几个小时的工作,我获得的最佳时间导致大约120秒的时间来运行某个测试(许多请求+网络延迟+无异步)
但这与我所需的资源相比还远远不够,在PHP的多处理失败后,我转向了Python。
几个小时后,我有了一个正在运行的Python多处理脚本,该脚本在20秒内运行,并且对超时有些不满意,然后又没有了。所使用的线程数,我将其降低到约10秒。
这是针对100%用PHP编写的网站,除了一个100行的Python脚本外。整个过程运行完美。
我的结论是,即使它无法每天为您提供帮助,您也可能会遇到这样的情况,至少了解并发编程的基础知识会极大地帮助您。
祝您好运,编码愉快!
PS:我并不是想抨击PHP,但是PHP根本不是适合当前工作的正确工具。
PS2:了解新技术或新的做事方式可以打开通往可能性新世界的大门。