# 并发(Concurrent)和并行(Parallel)的区别
并发(Concurrent)和并行(Parallel)的区别
# 1. 两者区别
- 并行是指两个或者多个事件在同一时刻发生
- 并发是指两个或多个事件在同一时间间隔发生
- 并行是在不同实体上的多个事件
- 并发是在同一实体上的多个事件
- 并行是在多台处理器上同时处理多个任务
- 并发是在一台处理器上同时处理多个任务
所以并发编程的目标是充分的利用处理器的每一个核,以达到最高的处理性能
# 2. 两者概况
并行(Parallel)指在同一时刻,有多条指令在多个处理器上同时执行。所以无论从微观还是从宏观来看,二者都是一起执行的
并发(Concurrent)指在同一时刻只能有一条指令执行,但多个进程指令被快速的轮换执行,使得在宏观上具有多个进程同时执行的效果,但在微观上并不是同时执行的,只是把时间分成若干段,使多个进程快速交替的执行
并行在多处理器系统中存在,而并发可以在单处理器和多处理器系统中都存在,并发能够在单处理器系统中存在是因为并发是并行的假象,并行要求程序能够同时执行多个操作,而并发只是要求程序假装同时执行多个操作(每个小时间片执行一个操作,多个操作快速切换执行)
当有多个线程在操作时,如果系统只有一个 CPU,则它根本不可能真正同时进行一个以上的线程,它只能把 CPU 运行时间划分成若干个时间段,再将时间段分配给各个线程执行,在一个时间段的线程代码运行时,其它线程处于挂起状态,这种方式我们称之为并发(Concurrent)
当系统有一个以上 CPU 时,则线程的操作有可能非并发。当一个 CPU 执行一个线程时,另一个 CPU 可以执行另一个线程,两个线程互不抢占 CPU 资源,可以同时进行,这种方式我们称之为并行(Parallel)
# 3. 多核CPU和多个CPU
当你将这一百只机器手全安装到一个机器人身上,这模式就是多核 CPU,当你将这一百只机器手分别两个的安装到 50 个机器人身上工作,这模式就是多个 CPU
当面临这些问题的时候,有两个关键词无法绕开,那就是并行和并发
- 并行:真正的同一时刻
- 并发:同一时间周期(我们感觉是同时执行,但是计算机执行周期是毫秒单位级别的,我们感觉不到)
首先,要先了解几个概念
- 进程是程序的一次执行
- 进程是资源分配的基本单位
- 一个进程可以包括多个线程
- 在单 CPU 计算机中,有一个资源是无法被多个程序并行使用的:CPU
- 操作系统调度器:拆分 CPU 为一段段时间的运行片,轮流分配给不同的程序(分时操作系统)
- 操作系统内存管理模块:管理物理内存、虚拟内存相关的事务
由于CPU同时刻只能执行一个进程,如果我们不加以控制的话,一个进程可能使用CPU直到运行结束,于是出现了操作系统调度器,而进程也成为了调度单位
进程的运行不仅仅需要CPU,还需要很多其他资源,如内存啊,显卡啊,GPS啊,磁盘啊等等,统称为程序的执行环境,也就是程序上下文
在这里就出现了并发的概念,调度器切换 CPU 给不同进程使用的速度非常快,于是在使用者看来程序是在同时运行,这就是并发,而实际上 CPU 在同一时刻只在运行一个进程。并发只是给人的假现象,原因就是由于 CPU 工作很快,不断地 loop 感觉是同时发生,实际都是单个执行的
CPU进程无法同时刻共享,但是出现一定要共享CPU的需求呢?此时线程的概念就出现了。线程被包含在进程当中,进程的不同线程间共享CPU和程序上下文(共享进程分配到的资源)
单 CPU 进行进程调度的时候,需要读取上下文 + 执行程序 + 保存上下文,即进程切换
如果这个 CPU 是单核的话,那么在进程中的不同线程为了使用 CPU 核心,则会进行线程切换,但是由于共享了程序执行环境,这个线程切换比进程切换开销少了很多。在这里依然是并发,唯一核心同时刻只能执行一个线程
出现线程的原因就是由于进程切换需要大量的资源切换,线程却还资源是共享的,切换速度很快,占用资源小,线程内容是隐私的,存储一些上下文信息,以及堆栈信息,占用内存很小,切换很快,同一进程不同线程切换共享进程资源,切换迅速
如果这个CPU是多核的话,那么进程中的不同线程可以使用不同核心,真正的并行出现了
多核才是并行,单核只能说是并发,假并行
线程是CPU调度和分配的基本单位,一定要和 进程是操作系统进行资源分配(包括cpu、内存、磁盘IO等)的最小单位 区别清楚。有句话说CPU只能看到线程,可以这么理解,假设我是CPU,我闭着眼,操作系统调度器将一个进程分配给我之后,我拿到进程睁开眼,我看到的是什么?我看到的是进程中的很多线程,那么我现在能调度和分配的是什么?进程?不行,因为我看不到其他进程,何来调度分配,只能调度我看到的那些线程,如果我是4核的话,把线程ABCD分配到核心1234,其他的线程依然要等待分配,至于等待多久,如何分配,暂不在本文讨论范围。于是线程是CPU调度和分配的基本单位
操作系统内存管理模块
最后说一下操作系统内存管理模块这里做的事:在这之前,程序员需要为每个程序安排运行的空间,这里的空间指的是内存的物理地址,但是这么的问题就是,每个程序都要协商如何使用同一内存的不同空间,而且程序员还要关心底层内存分配问题。解决办法就是,提出进程的概念,每个进程用一样的虚拟地址空间,CPU上增加了MMU模块负责转换虚拟地址和物理地址,虚拟地址经过操作系统和MMU之后,虚拟地址会映射到不同的物理地址,不同的进程就能获得各自独立的物理内存空间
另外在有的操作系统里,进程不是调度单位,线程是最基本的调度单位,调度器只调度线程,不调度进程,如 VxWorks
总结
- 单 CPU 中进程只能是并发,多 CPU 计算机中进程可以并行
- 单 CPU 单核中线程只能并发,单 CPU 多核中线程可以并行
- 无论是并发还是并行,使用者来看,看到的是多进程,多线程
# 4. 进程和线程
进程和线程根本区别:进程是操作系统资源分配的基本单位,而线程是任务调度和执行的基本单位
在开销方面:每个进程都有独立的代码和数据空间(程序上下文),程序之间的切换会有较大的开销; 线程可以看做轻量级的进程,同一类线程共享代码和数据空间,每个线程都有自己独立的运行栈和程序计数器(PC),线程之间切换的开销小。 所处环境:在操作系统中能同时运行多个进程(程序);而在同一个进程(程序)中有多个线程同时执行(通过CPU调度,在每个时间片中只有一个线程执行)
内存分配方面:系统在运行的时候会为每个进程分配不同的内存空间;而对线程而言,除了CPU外,系统不会为线程分配内存(线程所使用的资源来自其所属进程的资源),线程组之间只能共享资源。
包含关系:没有线程的进程可以看做是单线程的,如果一个进程内有多个线程,则执行过程不是一条线的,而是多条线(线程)共同完成的;线程是进程的一部分,所以线程也被称为轻权进程或者轻量级进程。
4核8线程实质
1核两线程(实现超线程),线程执行仍然并发执发,假并行;
最后说下我们最熟悉的东西4核8线程和6核12线程;
每个单位时间内,一个CPU只能处理一个线程(操作系统:Thread),以这样的单位进行,如果想要在一单位时间内处理超过一个线程是不可能的,除非是有两个CPU的实体单元。
多核心技术是将多个一样的CPU放置于一个封装内(或直接将两个CPU做成一个芯片),而英特尔的HT技术是在CPU内部仅复制必要的资源、让CPU模拟成两个线程;也就是一个实体核心,两个逻辑线程,在一单位时间内处理两个线程的工作,模拟实体双核心、双线程运作。 四核即代表着该CPU具有四个“CPU”,八线程则意味着每个CPU存有两个逻辑线程,总共有八个线程。就是超线程技术;
超线程技术是在一颗CPU同时执行多个程序而共同分享一颗CPU内的资源,理论上要像两颗CPU一样在同一时间执行两个线程,P4处理器需要多加入一个Logical CPU Pointer(逻辑处理单元)。因此新一代的P4 HT的的面积比以往的P4增大了5%。而其余部分如ALU(整数运算单元)、FPU(浮点运算单元)、L2 Cache(二级缓存)则保持不变,这些部分是被分享的。但是实际性能要比现在的物理双核差远了,也就是并发执行的;这样做的原因在于CPU处理的速度和内存或者寄存器或缓存 存取数据速度差别不是一个等量级的,我们实现超线程技术仍然满足不了CPU的胃口,因此是可能的,但是如果CPU经常处于满载的状态 时,那么还是卡,不如多核或多CPU
参考