并发和并行之间的区别是什么?
当前回答
并发是指两个或多个任务可以在重叠的时间段内启动、运行和完成。这并不一定意味着它们会同时运行。例如,在单核机器上进行多任务处理。
并行性是指任务实际上同时运行,例如在多核处理器上。
引用Sun的多线程编程指南:
并发:至少有两个线程正在进行时存在的条件。一种更为普遍的并行形式,可以将时间切片作为虚拟并行的一种形式。并行性:当至少两个线程同时执行时出现的情况。
其他回答
并发性=>在共享资源的重叠时间段内执行多个任务时(可能最大化资源利用率)。
并行=>当单个任务被划分为可以同时执行的多个简单的独立子任务时。
只是为了给其他好答案添加更多的澄清:
基于处理的抽象(CPU作为一个完全可以想象的例子)能够在同一时刻运行唯一的任务的前提,
并发是一个关于处理抽象的故事:它可以在不同的任务之间切换。
并行是一个关于我们有多个处理抽象的故事(例如,我们的CPU有多个内核)。因此,这是我们的系统能够同时执行多个任务的原因(字面意思)。但这里没有提到处理的特定抽象(它们是否并发)。
这里的重点是这些故事的内容。
因此,当您阅读公认答案时,请注意:
并发是指两个或多个任务可以在重叠的时间段。
严格地说,我们可以根据这个定义得出结论,并行性本身就是并发性的前提。
我将尝试用一个有趣且易于理解的示例进行解释。:)
假设一个组织组织了一场国际象棋比赛,10名棋手(棋艺相同)将挑战一名职业冠军棋手。由于国际象棋是一场1:1的比赛,因此组织者必须以高效的方式进行10场比赛,以便尽快完成整个比赛。
希望以下场景能够轻松描述进行这10场比赛的多种方式:
1) 串行-让我们假设专业人员与每个人逐一进行游戏,即与一个人开始和结束游戏,然后与下一个人开始下一场游戏,依此类推。换句话说,他们决定按顺序进行游戏。因此,如果一场比赛需要10分钟才能完成,那么10场比赛将需要100分钟,同样假设从一场比赛到另一场比赛的过渡需要6秒,那么对于10场比赛,则需要54秒(约1分钟)。
因此整个活动将在101分钟内完成(最差进场)
2) 同时-让我们假设职业球员轮到下一个球员,所以所有10名球员同时上场,但职业球员不是一次两个人,他轮到下一个人上场。现在假设一名职业球员需要6秒才能轮到他,而一名职业选手与两名选手的转换时间为6秒,那么回到第一名选手的总转换时间为1分钟(10x6秒)。因此,当他回到第一个与他一起开始比赛的人身边时,已经过去了2分钟(10xtime_per_turn_by-campion+10xtransition_time=2分钟)
假设所有玩家都需要45秒才能完成他们的回合,那么根据SERIAL事件的每场10分钟,游戏结束前的回合数应为600/(45+6)=11回合(约)
因此,整个事件将在11xtime_per_turn_by-player_&_champion+11xtransition_time_across_10_players=11x51+11x60sec=561+660=1221sec=20.35min(大约)内完成
从101分钟提高到20.35分钟(更好的方法)
3) 平行-假设组织者获得了一些额外的资金,因此决定邀请两名职业冠军选手(两人能力相同),并将同一组10名选手(挑战者)分成两组,每组5人,并将他们分配给两名冠军,即每组一人。现在,赛事在这两组比赛中并行进行,即至少有两名选手(每组一名)与各自组的两名职业选手进行比赛。
然而,在该组中,职业选手一次只带一名选手(即按顺序),因此无需任何计算,您可以很容易地推断出整个比赛将在101/2=50.5分钟内完成
看到从101分钟到50.5分钟的进步(好方法)
4) 并发+并行-在上述场景中,假设两名冠军选手将与各自组中的5名选手同时比赛(读第二分),因此现在跨组的比赛是并行运行的,但在组内,他们是同时运行的。
因此,一组游戏将在11xtime_per_turn_by-playerer_&_champion+1extransition_time_across_5_layers=11x51+11x30=600+330=930秒=15.5分钟(大约)内完成
因此,整个活动(包括两个这样的平行跑步组)大约将在15.5分钟内完成
看到从101分钟到15.5分钟的改进(最佳方法)
注意:在上述场景中,如果您用10个类似的工作替换10个玩家,用两个CPU核心替换两个职业玩家,则以下顺序仍然正确:
串行>并行>并发>并发+并行
(注意:此顺序可能会因其他情况而改变,因为此顺序高度依赖于作业之间的相互依赖性、作业之间的通信需求以及作业之间的转换开销)
我认为在这个问题上有两种不同的观点导致了混淆:程序员的观点(并发/并行编程)与计算机/操作系统的观点(并行/并行执行)。
这里回答了计算机的观点。
程序员的观点:
并发编程:程序员编写代码时知道代码将由多个线程执行,无论出于何种原因。原因可能是:在等待I/O时更好地利用CPU,通过不同线程处理Web请求,通过在独立于主线程的线程中运行计算,运行周期性后台任务,使GUI做出响应。程序员必须应用互斥构造、锁定/解锁、等待条件/信号、处理死锁等。多个线程可以在单个处理器/内核上运行(从计算机的角度来看是并发的),也可以在多个内核上运行。
并行编程:程序员知道程序将在具有多个处理器/内核的计算机上运行,并希望利用多个内核。程序员将CPU密集型计算划分为多个子任务,在一个线程中运行每个子任务,一旦线程完成,其结果将合并为总结果(分而治之)。例如,将一些矩阵处理代码划分为并行处理矩阵部分的任务。每个核心将使用子任务执行一个线程(如果线程数大于内核数,则同时执行多个线程)。程序员也必须在这里应用并发的编程构造,但她也关注将任务划分为子任务并合并结果。例如,在Java中,程序员可以使用ParallelStreams来分割数据并自动合并结果。如果程序员知道程序将在单核处理器上执行,那么将CPU密集型任务拆分为多个线程是没有好处的。摘自Doug Leah的《Java并发编程:设计原则和模式》,1999年第2版,第343页:
并行程序专门设计为利用多个CPU来解决计算密集型问题。
同意:具有共享资源潜力的多个执行流
前任:两个线程竞争I/O端口。
视差:将问题分成多个相似的块。
前任:通过对文件的每一半运行两个进程来解析大文件。
推荐文章
- 什么是ORM,它是如何工作的,我应该如何使用它?
- 我能在服务器端应用程序(PHP、Ruby、Python等)上读取URL的哈希部分吗?
- 多少个参数是太多?
- 对于不可变集合上的非突变“add”方法,最好的名称是什么?
- foo到底是什么意思?
- foreach和map有区别吗?
- 设计模式:工厂vs工厂方法vs抽象工厂
- 为什么处理排序数组比未排序数组慢?
- 构造函数何时抛出异常是正确的?
- Thread start()和Runnable run()有什么区别
- 什么是“一级”对象?
- 什么时候应该使用Debug.Assert()?
- 为什么浮点数不准确?
- IOException:进程不能访问文件“文件路径”,因为它正在被另一个进程使用
- 地图和字典的区别是什么?