《并发哲学:从编程入道到开悟升天》4.5 毕竟是人脑创造了电脑
毕竟是人脑创造了电脑
本章我们围绕代码,问出了很多为什么,我称之为问道。
- 为什么并发如此重要的能力在计算机编程发展早期迟迟没有得到大幅度改良,相关的研究没有推进?
- 为什么线程和进程的概念总是经常被提及,但本书阐述的并发编程却感觉丝毫不涉及?
- 当基于协程的并发建模抽象逐渐成为主流,我的代码建模思想应该做出怎样的调整?
本章回答了这些问题,但价值不仅仅停留在这些问题。
对第一个问题,我们详细阐述了因为并发而引入的数据竞争、锁和更多的安全问题,这些安全问题有些可以通过工具来严格避免,但更多的则是不可以。面对各种问题,在并发代码逻辑上处理的每一步我们都需要小心翼翼。好在Golang提供了高层抽象,我们可以没必要考虑一些太底层的东西,虽然还有危险,但至少我们看到了光明。
对第二个问题,关系到一个止部抽象链的概念。我们是否愿意暴露更多的细节给开发人员层面去调度?如果选择是,大部分的以线程为并发调度单元最高抽象层次的编程语言都是这么做的,这带来了更大的灵活性,许许多多的问题和文章围绕这种巨大的灵活性开展讨论,但很快我们发现了问题——我们陷入了讨论技术问题而不是解决实际需求的怪圈。
还好,Golang为首的语言抽象出了更高层,即便这种比线程还要更加灵活的调度方式理论上会比线程调度更加的复杂和不可捉摸,但是Golang通过语法层面屏蔽,止步了开发人员的抽象成本。从进程,到线程再到协程,这是一条计算机并发调度单元层层抽象的抽象链,通过停止延伸并只关注部分抽象链,开发人员能够投入更大的精力关注在实际代码问题的解决上。正如4.2节案例内提到的编程案例——李华的早晨,我们通过朴素的生活描述,经过简单的代码建模,最终无脑实现已有元素拼接,就构建了几乎完全正确的并发代码。
很长一段时间由于不得不考虑线程的存在——线程同时作为了一种调度抽象和CPU执行实体,我们往往会产生并发和并行混淆的错觉。实际上,并发和并行探讨的是完全不同的两个层面:
- 并发探讨的是对多个任务的分配、调度和切换问题,力图解决渴望并行执行与实际实体不足的矛盾,最终通过并发设计、并发代码来缓解这一矛盾。
- 并行是一种客观状态描述,通过划分不同的代码片段,将事物的运行定义同时性,描述事物运行时间片的重叠。
止部抽象链还有一个好处,就是可以将并发和并行的讨论几乎完全的分离。通过并发并行分离,我们通过构建朴素世界观下逻辑正确的代码,就可以合理期望我们的代码最终能够使得对应的任务尽可能以并行的姿态运行。我们严肃的考虑个人理想,而不用在乎自然规律,这无疑对代码建模和分析是具有重大变革意义。
就好比几乎没有人会关心丢出去石头的飞行和自己接下来的奔跑这两件事情是否是并行的问题一样。我们比前人无比接近最原始的朴素世界抽象。
既然有了朴素世界抽象,我们便可以通过代码感悟哲理。在4.4节中,我们总结了在之前文章中提到的基于Golang代码对日常生活哲理的感悟。有些事情看似是摸不着头绪的感性,但通过代码的严格量化,我们将预期结果可视化,基于可视化的结论,相信聪明的你应该明白怎么做。
回首本章,并发技术的变革历史,无疑是在硅基生命的发展旅程中,实现了类似人类的一次究极进化。大自然赋予各种生物高水平协作的能力,以人类为首的高智慧水平生物,又开始在自己的世界内,尝试为创造的实体赋予灵活协调和推进任务进行的能力。不禁感叹,毕竟是人脑创造了电脑,我们在体会电脑程序效率与秩序进化的时候,也在无时无刻不在体会大自然给我们的馈赠。