要搞清楚什么是同步,异步,串行,并行,并发,进程,线程,协程
在实际开发过程中很多人会因为同步,异步,串行,并行,并发,进程,线程,协程 等名词搞混,搞不清楚这些名称到底代表的是什么意思。其实这也是实际开发中必须掌握一些知识点。掌握和理解这些概念也有助于我们去更好的去开发。
一、同步、异步:
指的是能否开启新的线程。同步不能开启新的线程,异步可以。
同步:在程序中同步指的就是顺序执行,执行完一个再执行下一个,需要等待、协调运行(代码由上而下依次执行)。
异步:异步和同步是相对的,异步就是彼此独立,在等待某事件的过程中可以继续去做自己的事情,不需要等待这一事件完成后再工作。线程就是实现异步的一个方式。异步是让调用方法的主线程不需要同步等待另一线程的完成,从而可以让主线程继续干其它的事情。
异步和多线程并不是一个同等关系,异步是最终目的,多线程只是我们实现异步的一种手段。异步是当一个调用请求发送给被调用者,而调用者不用等待其结果的返回而可以做其它的事情。 实现异步可以采用多线程技术或则交给另外的进程来处理。
二、串行、并行:
串行和并行指的是任务的执行方式。
串行:是指多个任务时,各个任务按照顺序执行,完成一个之后才能进行下一个。
并行:指的是多个任务可以同时执行。举个栗子:比如在你的程序中你需要调用 A 接口,A 接口调用完毕之后 接着调用 B 接口,而为了优化性能,我们就可以使用并行的方式来处理,也就是说同时请求 A 接口和 B 接口,不需要 A 接口请求完毕后,在去请求 B 接口。
三、并发:
3.1:并发是什么?
并发是指立即处理多个任务的能力。一个例子就能很好地说明这一点。
我们可以想象一个人正在跑步。假如在他晨跑时,鞋带突然松了。于是他停下来,系一下鞋带,接下来继续跑。这个例子就是典型的并发。这个人能够一下搞定跑步和系鞋带两件事,即立即处理多个任务。
3.2:并行是什么?并行和并发有何区别?
并行是指同时处理多个任务。这听起来和并发差不多,但其实完全不同。(虽然上面我们已经说了什么是并行,但是这里还是在强调一下吧!)
这里同样用这个跑步的例子来帮助理解。假如这个人在慢跑时,还在用他的 iPod 听着音乐。在这里,他是在跑步的同时听音乐,也就是同时处理多个任务。这称之为并行。
3.3:从技术上看并发和并行
通过现实中的例子,我们已经明白了什么是并发,以及并发与并行的区别。作为一名极客,我们接下来从技术的角度来考察并发和并行。:)
假如我们正在编写一个 web 浏览器。这个 web 浏览器有各种组件。其中两个分别是 web 页面的渲染区和从网上下载文件的下载器。假设我们已经构建好了浏览器代码,各个组件也都可以相互独立地运行(通过像 Java 里的线程,或者通过即将介绍的 Go 语言中的 Go 协程来实现)。当浏览器在单核处理器中运行时,处理器会在浏览器的两个组件间进行上下文切换。它可能在一段时间内下载文件,转而又对用户请求的 web 页面进行渲染。这就是并发。并发的进程从不同的时间点开始,分别交替运行。在这里,就是在不同的时间点开始进行下载和渲染,并相互交替运行的。
如果该浏览器在一个多核处理器上运行,此时下载文件的组件和渲染 HTML 的组件可能会在不同的核上同时运行。这称之为并行。
上一张图来看并发和并行的区别:
并行不一定会加快运行速度,因为并行运行的组件之间可能需要相互通信。在我们浏览器的例子里,当文件下载完成后,应当对用户进行提醒,比如弹出一个窗口。于是,在负责下载的组件和负责渲染用户界面的组件之间,就产生了通信。在并发系统上,这种通信开销很小。但在多核的并行系统上,组件间的通信开销就很高了。所以,并行不一定会加快运行速度!
3.4:再次强调:并发不是并行!!!
并发主要由切换时间片来实现"同时"运行,并行则是直接利用多核实现多线程的运行,go 可以设置使用核数,以发挥多核计算机的能力。
3.5:并发和并行的总结
A. 多线程程序在一个核的 cpu 上运行,就是并发。
B. 多线程程序在多个核的 cpu 上运行,就是并行。
四、扯个本文章标题的题外话:Go(Golang)语言对并发的支持
Go 编程语言原生支持并发。Go 语言的并发通过 goroutine(协程) 特性完成。goroutine 类似于线程,但是可以根据需要创建多个 goroutine 并发工作。goroutine 是由 Go 语言的运行时调度完成,而线程是由操作系统调度完成。
Go 语言还提供 channel 在多个 goroutine (协程) 间进行通信。goroutine 和 channel 是 Go 语言秉承的 CSP(Communicating Sequential Process)并发模式的重要实现基础。
goroutine(协程) 奉行通过通信来共享内存,而不是共享内存来通信。
4.1、进程和线程:
A. 进程是程序在操作系统中的一次执行过程,系统进行资源分配和调度的一个独立单位。即:一个运行中的程序,就是进程。
B. 线程是进程的一个执行实体,是 CPU 调度和分派的基本单位,它是比进程更小的能独立运行的基本单位。
C. 一个进程可以创建和撤销多个线程;同一个进程中的多个线程之间可以并发执行。
4.2、协程和线程:
协程:独立的栈空间,共享堆空间,调度由用户自己控制,本质上有点类似于用户级线程,这些用户级线程的调度也是自己实现的。
线程:一个线程上可以跑多个协程,协程是轻量级的线程。
goroutine 只是由 go 官方实现的超级"线程池"。
每个实力 4~5KB 的栈内存占用和由于实现机制而大幅减少的创建和销毁开销是 Go 高并发的根本原因。
版权声明: 本文为 InfoQ 作者【乌龟哥哥】的原创文章。
原文链接:【http://xie.infoq.cn/article/85a59844fa4f61ff8b321451c】。文章转载请联系作者。
评论