一文读懂并发与并行

一文读懂并发与并行,第1张

并发性和并行性通常用于与多线程程序相关的,最早并发性和并行性似乎指的是相同的概念,但其实并发和并行实际上有不同的含义。在这个并发与并行教程中,我将解释这些概念的含义。

为了清楚起见,在本文中,我讨论在单个应用程序(单个进程)中的并发性和并行性。不在多个应用程序、进程或计算机之间。

如果您喜欢视频,这里有本教程对应的视频版本: 并发与并行教程视频

并发是指在一个应用程序中同时存在多个任务在执行,同时刻或者说看起来是同一时刻(并发)。

如果计算机只有一个CPU,应用程序可能不会在同一时间完成多个任务,但在应用程序内部一次完成多个任务。要同时在多个任务上取得进展,CPU会在执行期间在不同的任务之间切换。如下图所示:

并行执行是指计算机具有多个 CPU 或 CPU 内核,并同时在多个任务上取得进展。但是,并行执行并不是指与并行性相同的现象 。稍后我将回到并行性。并行执行如下图所示:

可以进行并行并发执行,其中线程分布在多个 CPU 中。因此,在同一个 CPU 上执行的线程是并发执行的,而在不同 CPU 上执行的线程是并行执行的。下图说明了并行并发执行。

并行性意味着一个应用程序将其任务拆分成更小的子任务,这些子任务可以并行处理,例如在多个CPU上同时处理。因此,并行性并不是指与并行执行相同的执行模型,即使它们表面上看起来很相似。

为了实现真正的并行性,您的应用程序必须运行多个线程,每个线程必须在单独的 CPU/CPU 内核/显卡 GPU 内核或类似内核上运行。

下图显示了一个更大的任务,它被分为4个子任务。这4个子任务由4个不同的线程执行,它们运行在2个不同的CPU上。这意味着,这些子任务的部分是并行执行的(在同一CPU上执行的),而部分是并行执行的(在不同CPU上执行的)。

如果这4个子任务由4个线程在各自的CPU上执行(总共4个CPU),那么任务的执行将是完全并行的。然而,要将一个任务分解成与可用CPU数量一样多的子任务并不总是那么容易。通常,将一个任务分解为多个子任务更容易,这些子任务与手头的任务自然匹配,然后让线程调度器负责在可用CPU之间分配线程。

综上所述,并发性指的是多个任务在单个CPU上看似同时取得进展。

另一方面,并行性与应用程序如何并行执行单个任务有关,通常是通过将任务拆分为可以并行完成的子任务。

这两种执行方式可以在同一个应用程序中组合。我将在下面介绍其中一些组合。

应用程序可以是并发的,但不能是并行的。这意味着它似乎同时(同时)在多个任务上取得进展,但应用程序会在每个任务上取得进展之间切换,直到任务完成。在并行线程/CPU中没有真正的任务并行执行。

应用程序也可以是并行的,但不能是并发的。这意味着应用程序一次只能处理一个任务,而这个任务被分解成可以并行处理的子任务。但是,每个任务(+子任务)都是在下一个任务被拆分并并行执行之前完成的。

此外,应用程序既不能是并发的,也不能是并行的。这意味着它一次只能处理一个任务,而且任务永远不会分解为并行执行的子任务。小型命令行应用程序可能就是这种情况,因为它只有一个作业,太小了,无法并行化。

最后,应用程序还可以通过两种方式同时并发和并行:

第一种是简单的并行执行。如果应用程序启动多个线程,然后在多个CPU上执行,就会发生这种情况。

第二种方式是应用程序同时处理多个任务,并将每个任务分解为子任务,同时以并行的方式执行。但是在这种情况下,并发和并行的一些性能优势可能会丢失,因为计算机中的 CPU 基于在频繁于并发或并行处理。所以并发且并行,可能只会带来微小的性能提升甚至可能是性能损失。因此,除非有特殊目的并且已经提前进行了充分分析和测量,否则不建议采用并发并行模型。

(本篇完)

一、判断题(正确用T表示,错误用F表示,共5题,每题2分,共10分)

1.在多道程序系统中,只有相关的并发进程才有可能存在通信问题。A

A T

B F

2.并发问题是多处理机系统主要关注的焦点,而对但处理机系统无任何影响。B

A T

B F

3 在消息传递通信机制中,只有消息的接收者才能采用阻塞方式进行通信。B

A T

B

F

4.进程之间的直接制约关系可以归结为共享数据与交换数据。A

A T

B

F

5.消息传递通信机制提供了同步和通信功能,这些都是相互交互的进程间必须的。A

A T

B F

二、单项选择题(共10题,每题4分,共40分)

1.进程通信,是指___C__之间交换信息。

A 程序

B 模块

C 进程

D 线程

2.信箱通信是一种___B__通信方式。

A 直接

B 间接

C 低级

D

信号量

3.进程间通信是协调解决多个进程之间的约束关系,实现进程共同进展的关键技术,是多道系统中控制进程___D__执行必不可少的机制。

A 动态

B 并行

C 异步

D 并发

4.下述哪一个选项体现了原语的主要特点_A___。

A 不可分割性

B 并发性

C

共享性

D

异步性

5.缓冲区属于__B___。

A

高级通信

B 低级通信

C 直接通信

D 间接通信

6.消息传递系统中,进程间的数据交换以消息为单位,用户直接利用系统提供的一组__C___来实现通信。

A 程序

B 线程

C

原语(通信命令)

D

管道

7.管道通信中,管道由OS核心的缓冲区来实现,信息传递的方向是__A___的。

A 单向

B

双向

C 既可单向也可双向

D

不确定

8.要进行管道通信,首先建立需要通信的___D__,然后在它们之间建立一个通信管道。

A 程序

B

进程

C 信箱

D 管道

9.缓冲区通信是一种___C__通信方式。

A 直接通信

B 间接通信

C

低级通信

D

信号量

10.引入缓冲的主要目的是__C___。

A

节省内存

B 提高CPU的利用率

C 改善CPU和I/O设备之间速度不匹配的情况

D 提高I/O设备的效率

三、填空题(共5题,每题4分,共20分)

1.进程通信分低级通信和高级通信。将只能传递状态和控制信息的通信称为_____,而将进程间交换较多信息的通信称为_____。

答:低级通信,高级通信

2.进程间通信方式包括直接通信方式和间接通信方式。其中,_____借助于收发双方进程之外的共享数据结构作为通信中转。

答:信箱通信

3.进程间通信的类型可分为共享存储器通信、____通信以及____通信等三大类。

答:消息传递,管道

4.为了使诸进程间能协调地进行通信,必须对进程通信的_____双方进行进程同步。

答:收、发

5.管道通信中的管道是一条在进程间以_____传送的通信通道。

答:字节流方式

四、 简答题(共3题,每题10分,共30分)

1.什么是进程通信?

答:进程通信是指两个并行进程可以通过互相发送消息进行合作,消息是通过消息缓冲而在进程之间相互传递的。

2.试比较进程间的低级与高级通信工具?

答:用户用低级通信工具实现进程通信很不方便,效率低,通信对用户不透明,所有 *** 作都必须由程序员来实现,而高级通信工具弥补了这些缺陷,用户直接利用 *** 作系统提供的一组通信命令,高效地传送大量的数据。

3.进程通信的类型有哪几种?它们分别适合于何种场合?

答:共享存储器:在内存种分配一片空间作为共享存储区。需要进行通信的进程把它附加到自己的地址空间中,不需要时则把它取消。 管道文件:它是连接两个命令的一个打开文件。一个命令向该文件中写入数据,为写者;另一个命令从该文件中读出数据,为读者。 消息传递:它以消息为单位在进程间进行数据交换。

在 *** 作系统中,并发是指一个时间段中有几个程序都处于已启动运行到运行完毕之间,且这几个程序都是在同一个处理机上运行,但任一个时刻点上只有一个程序在处理机上运行。

在关系数据库中,允许多个用户同时访问和更改共享数据的进程。SQL Server 使用锁定以允许多个用户同时访问和更改共享数据而彼此之间不发生冲突。

上面是百度百科上的回答 , 

通俗点的解释 , 一个冰箱 , 一家人在用 ,  最极端的情况 , 一家人在晚餐的时候 同一时间点都要从冰箱里面拿东西 , 也是排队拿, 但是交给电脑处理类似的逻辑 ,这就是错误的, 并发的存在就是保证这样的错误不会发生 ,

程序并不能单独运行,只有将程序装载到内存中,系统为它分配资源才能运行,而这种执行的程序就称之为进程。程序和进程的区别就在于:程序是指令的集合,它是进程运行的静态描述文本;进程是程序的一次执行活动,属于动态概念

主要归咎于两点 一个是由实现决定的,一个是由需求决定的

线程由线程ID,程序计数器(PC)[用于指向内存中的程序指令],寄存器集合[由于存放本地变量和临时变量]和堆栈[用于存放方法指令和方法参数等]组成。

以 Unix/Linux 的体系架构为例。

因为 *** 作系统的资源是有限的,如果访问资源的 *** 作过多,必然会消耗过多的资源,而且如果不对这些 *** 作加以区分,很可能造成资源访问的冲突。所以,为了减少有限资源的访问和使用冲突,对不同的 *** 作赋予不同的执行等级(有多大能力做多大的事),用户态(User Mode)和内核态(Kernel Mode)。

运行于用户态的进程可以执行的 *** 作和访问的资源都会受到极大的限制,而运行在内核态的进程则可以执行任何 *** 作并且在资源的使用上没有限制。

并发 :一个时间段内有很多的线程或进程在执行,但何时间点上都只有一个在执行,多个线程或进程争抢时间片轮流执行。

并行 :一个时间段和时间点上都有多个线程或进程在执行。

线程有三种模型, 一对一,多对一,多对多具体参考 一篇文章读懂Java多线程模型 , 这里只描述一对一的情况

每个用户线程都映射到一个内核线程,每个线程都成为一个独立的调度单元,由内核调度器独立调度,一个线程的阻塞不会影响到其他线程,从而保障整个进程继续工作

JVM 没有限定 Java 线程需要使用哪种线程模型来实现, JVM 只是封装了底层 *** 作系统的差异,而不同的 *** 作系统可能使用不同的线程模型,例如 Linux 和 windows 可能使用了一对一模型,solaris 和 unix 某些版本可能使用多对多模型。所以一谈到 Java 语言的多线程模型,需要针对具体 JVM 实现。

Sun JDK 12开始,线程模型都是基于 *** 作系统原生线程模型来实现,它的 Window 版和 Linux 版都是使用系统的 1:1 的线程模型实现的。

编程对于很多人来说,还是比较好上手的。当你学会了一门语言,可以编写一些程序了,很快就会遇到一道坎,并发编程,单线程下好好跑着的程序,怎么就运行异常了?怎么就得不到期望的结果。在面试中,并发编程也是经常出现,我们今天来讨论一个问题, 并发编程,容易出哪些问题?

相信大家在学习并发编程的时候,都会遇到这样一个经典问题,有一个函数,执行i=i+1,执行1000遍。在单线程的环境下,得到的结果都是预期的1000。如果是两个线程同时运行,那么,得到的结果可能是2000,也有可能小于2000。

这是因为i=i+1不是一个原子 *** 作,我们会获取i的值,然后执行一次加法运算,最后将结果赋值给i。当多个线程执行的时候,获取到的i的值之后,在执行后面的动作之前,另外一个线程已经修改了i,造成最终的结果小于2000。

并发编程的时候,我们往往无法确定多个线程之间的执行顺序,经常我们会出现这样一个错误。我们在一个线程中使用的变量,会在另外一个线程中进行初始化或者赋值。最常见的,便是我们在主线程上创建一个子线程,然后再进行变量的初始化,子线程的执行可能早于父线程,造成程序错误。

为了解决并发问题,我们通常会引入锁、信号、信号量等手段来保证临界区只会被一个线程访问,或者让一个线程等待另外一个线程执行完成。但是,引入锁之后,我们又可能会出现死锁的问题,例如:线程1与线程2都需要抢占AB两把锁,假设线程1先抢占了A锁,线程2抢占了B锁,这个时候,线程1在等待B锁,线程2在等待A锁,就这样,等到海枯石烂,我们称之为死锁。

出现死锁,需要同时满足下面几个条件:1线程需要对需要的资源进行互斥访问(例如一个线程抢到锁)2持有并等待(例如一个线程抢到了A锁,然后在等待B锁)3非抢占(线程抢到了锁之后,不能被其他线程抢到)4循环等待,线程之前存在一个环路。

那么,如何解决死锁的问题呢?既然出现死锁需要同时满足上面的几个条件,那么,我们只要破坏其中一个条件,就能够避免死锁问题。

今天,我们了解到并发编程带来的问题与解决方案,希望对你在平时的工作或者面试有所帮助。

以上就是关于一文读懂并发与并行全部的内容,包括:一文读懂并发与并行、计算机 *** 作判断题求解、为什么要并发,并发有什么优点我觉得并发不能提高程序的执行速度等相关内容解答,如果想了解更多相关内容,可以关注我们,你们的支持是我们更新的动力!

欢迎分享,转载请注明来源:内存溢出

原文地址: http://outofmemory.cn/zz/10139645.html

(0)
打赏 微信扫一扫 微信扫一扫 支付宝扫一扫 支付宝扫一扫
上一篇 2023-05-05
下一篇 2023-05-05

发表评论

登录后才能评论

评论列表(0条)

保存