当前位置:首页>python>《Python 从入门到精通》132|多任务的基本概念:同步、异步、并发、并行

《Python 从入门到精通》132|多任务的基本概念:同步、异步、并发、并行

  • 2026-09-03 07:02:42
《Python 从入门到精通》132|多任务的基本概念:同步、异步、并发、并行

学到这里,很多人都会遇到一个非常真实的问题。

程序能写了,功能也能实现了,可一旦任务多起来,速度就开始不对劲。

比如你要同时下载多个文件。 比如你要批量请求很多网页。 比如你要一边处理数据,一边等数据库返回结果。 比如你做自动化脚本时,明明每一步都不复杂,可整个程序执行起来就是特别慢。

这时候,你就会接触到几个高频词:

同步 异步 并发 并行

很多初学者第一次看到这些词,会觉得特别绕。明明都和多任务有关,为什么还要分这么细。更麻烦的是,这几个词经常一起出现,一不小心就混了。

这一章,我们不急着写复杂代码,先把这几个概念真正讲明白。因为后面学多线程、多进程、协程时,能不能学顺,很大程度上取决于你现在能不能把这些基础概念分清。

一、什么叫多任务

先不要急着看同步异步,先把多任务这三个字理解透。

所谓多任务,说白了,就是程序不只做一件事,而是要处理多件事。

比如一个下载工具,要下载 10 个文件。 比如一个爬虫,要抓取 100 个页面。 比如一个聊天软件,要一边接收消息,一边发送消息。 比如一个办公脚本,要同时读取很多文档,再分别整理输出。

这些都属于多任务场景。

注意,这里的多任务,不一定真的是同一时刻做很多事。它更准确的意思是,程序要面对多个任务,而不是只干一件单线程的小事。

理解这一点很重要。因为后面你会发现,有的多任务是轮流做的,有的多任务是真的同时做的,这就引出了并发和并行的区别。

二、先从最容易理解的同步开始

同步,其实是我们最熟悉的一种执行方式。

它的特点很简单:

一件事做完,再做下一件事。 前一步没结束,后一步就得等着。

比如下面这段代码:

import timedeftask1():    print("开始任务1")    time.sleep(2)    print("任务1结束")deftask2():    print("开始任务2")    time.sleep(2)    print("任务2结束")task1()task2()

执行顺序一定是这样的:

先执行任务1 等任务1彻底做完 再去执行任务2

这就是同步。

同步最大的特点,不是慢,而是顺序明确。它像排队办事,一个窗口一个人,前面没办完,后面就不能插进来。

这种方式的优点是逻辑简单,代码容易理解,排查问题也方便。缺点也很明显,只要某一步卡住了,后面的任务就全都得等。

所以,同步最适合那种步骤之间依赖很强、必须按顺序推进的场景。

比如:

先登录,再获取个人信息 先读取配置,再执行任务 先生成数据,再写入文件

这些场景本来就有前后依赖,用同步写最自然。

三、同步为什么会让人觉得慢

同步真正让人难受的地方,不是做事本身,而是等待。

举个例子。

假设你要请求 3 个网页,每个网页响应都需要 2 秒。如果用同步方式写,大概就是这样:

import timedefrequest_page(name):    print(f"{name} 开始请求")    time.sleep(2)    print(f"{name} 请求结束")request_page("页面1")request_page("页面2")request_page("页面3")

总耗时大概是 6 秒。

为什么这么久?

因为这 3 个任务是一个一个做的。页面1等完了,才能轮到页面2,页面2结束了,页面3才开始。程序在等待页面返回数据的时候,其实什么别的事都没做。

这就是同步模式最典型的性能浪费。

不是工作太难,而是等的时候太老实了。

四、异步到底是什么意思

很多人看到异步这两个字,第一反应是:

是不是异步就是同时执行。

这其实不够准确。

异步更本质的意思是:

当程序遇到需要等待的操作时,不傻等,先去做别的事,等时机到了再回来继续处理。

注意,这里最关键的词,不是同时,而是不要堵住。

举个生活化的例子。

你去餐厅点餐。

同步像什么呢。你点完一份炒饭,然后站在厨房门口一直等,厨师没做好之前,你什么都不干。

异步像什么呢。你点完炒饭之后,先去找座位,顺便拿餐具、倒水、看消息。等饭好了,服务员再叫你。

这就是异步。

异步并不一定意味着多个任务真正同时在跑,它强调的是:遇到等待时,不要把时间白白浪费掉。

所以,异步特别适合那种等待时间很多的场景,比如网络请求、磁盘读写、数据库访问、消息收发。

五、同步和异步,核心区别到底在哪

你可以把它们的差别记成一句很直白的话:

同步是等着做 异步是先去做别的,回头再处理

再说得具体一点。

同步模式下,任务执行到某一步,如果这里要等,那整个流程就暂停在这里。

异步模式下,任务执行到某一步,如果这里要等,程序会把这个等待先挂起来,然后去推进别的任务。等条件满足,再回来接着做。

也就是说,异步的价值主要体现在等待型任务里。

如果任务本身没什么等待,而是一直在疯狂计算,那异步未必能帮你多少。因为它能优化的是等待时间,不是纯计算能力。

这一点你一定要提前记住。后面很多人学协程效果不理想,本质上就是任务类型没搞对。

六、再说并发,这个词最容易被误解

并发是很多人最容易混淆的概念。

你经常会听到一种说法:

并发就是多个任务一起做。

这话不能说错,但太粗糙了。

更准确一点,并发指的是:

在一段时间内,多个任务都在推进。

这里注意,是在一段时间内都在推进,不一定是某一个绝对瞬间真正同时执行。

举个例子。

你有 3 个任务要做:

回邮件 整理表格 下载资料

如果你是这样处理:

先回一点邮件 等下载时,切去整理表格 表格处理中间又去看一眼邮件 再回头继续下载任务

这种感觉,就是并发。

多个任务交替推进,谁也不是从头到尾一口气做完,但整体都在往前走。

所以,并发的重点是任务管理上的重叠,而不是物理意义上的绝对同时。

七、并发不等于并行

这是必须分清的一组概念。

很多人把并发和并行当成一个东西,其实它们不一样。

并发强调的是:

多个任务看起来是一起推进的。

并行强调的是:

多个任务在同一时刻真的同时执行。

这两个词最大的区别在于,是否真的同一时间一起跑。

举个简单例子。

你一个人做三件事,一会儿看锅,一会儿切菜,一会儿洗菜。这叫并发。因为这些事在同一段时间里都在推进,但你毕竟只有一个人,不可能同一秒同时切菜和洗菜。

如果你和另外两个人一起做饭,一个人切菜,一个人洗菜,一个人看锅,这就更接近并行。因为不同任务真的在同一时刻由不同执行单元同时进行。

所以你可以这样理解:

并发像一个人来回切换处理多件事。 并行像多个人同时各干各的事。

这个比喻虽然不完全等价,但对初学者来说非常好理解。

八、为什么单核 CPU 也能实现并发

很多人听到并发之后,会问一个问题:

如果电脑只有一个核心,怎么可能同时处理多个任务。

答案是,可以通过快速切换来实现。

CPU 虽然同一时刻只能执行一个任务,但它切换得非常快。快到人几乎感觉不出来,于是你就会觉得多个任务像是在一起进行。

就像你看动画片,其实一张张图片是连续切换出来的,只不过切换速度够快,你就以为它动起来了。

程序里的并发,很多时候也是这个道理。

多个任务并不是每一瞬间都真的一起跑,而是 CPU 在它们之间快速来回切换,于是从整体效果上看,多个任务都在推进。

这也是为什么并发和并行不能混为一谈。

并发可以只靠调度和切换实现。 并行通常需要多个执行单元,比如多核 CPU。

九、并行到底适合什么场景

并行最适合的,是那种可以拆开、彼此独立、而且计算量比较大的任务。

比如:

大批量图片处理 视频转码 复杂数学运算 大规模数据计算

这类任务如果能拆成多个子任务,交给多个核心同时处理,整体速度就可能明显提升。

举个简单理解。

假设你有 1000 张图片要缩放。

同步做法是,一张一张处理。 并发做法可能是任务在不同处理流程之间切换推进。 并行做法则是把图片分给多个执行单元,同时处理不同部分。

因为图片之间互不依赖,所以很适合并行。

但如果任务之间前后依赖特别强,比如必须先做 A 再做 B,再做 C,这种场景并行效果就有限了。

所以并行不是万能加速器,它也要看任务本身能不能拆。

十、同步、异步、并发、并行,这四个词到底是什么关系

学到这里,我们把这四个概念重新整理一遍。

同步和异步,描述的是任务执行时,遇到等待该怎么处理。

同步是等当前任务做完,再继续。 异步是当前任务要等时,先去推进别的任务。

并发和并行,描述的是多个任务之间的推进关系。

并发是在一段时间内,多个任务都在推进。 并行是在同一时刻,多个任务真的同时执行。

这两组概念不是互相排斥的,而是可以组合出现。

比如:

异步并发 多线程并发 多进程并行

也就是说,同步异步是一组维度,并发并行又是另一组维度。

很多初学者之所以觉得乱,就是因为把两套分类混在一起理解了。

你只要记住:

同步异步,关注的是等不等。 并发并行,关注的是是不是一起推进、是不是同时执行。

脑子里一下就清楚多了。

十一、一个特别容易混淆的误区

很多人会说:

异步就是并发。 多线程就是并行。 程序只要用了异步就一定快。

这些说法都不严谨。

先说第一句,异步就是并发。

不完全对。异步通常可以帮助实现并发效果,但异步本身强调的是等待时不阻塞,而并发强调的是多个任务在一段时间内共同推进。两者关系密切,但不是一个概念。

再说第二句,多线程就是并行。

也不一定。多线程有时候是并发,有时候能接近并行效果,得看具体语言机制、运行环境和任务类型。不能一概而论。

最后一句,异步一定快。

这更不对。异步只是在适合它的场景里更高效。比如网络请求很多、等待时间很多,它可能非常有优势。但如果是大量纯计算任务,异步不一定能帮上忙。

所以以后看到这些概念,别急着直接和速度划等号。先看任务是什么,再看工具适不适合。

十二、一个最通俗的总比喻

如果你还是觉得抽象,那我用一个生活里的场景,把它们一起讲透。

假设你要洗衣服、做饭、打扫卫生。

同步是什么。 先洗衣服,洗完再做饭,做完再打扫。一步一步来。

异步是什么。 你先把衣服塞进洗衣机开始洗,机器转的时候你去切菜,锅在炖的时候你去扫地。谁需要等待,就先放一边,去做别的。

并发是什么。 在这一小时里,洗衣、做饭、打扫这几件事都在推进。虽然你没有真正同一秒干三件事,但整体都在往前走。

并行是什么。 你、家人、扫地机器人同时分别干不同的活,多个任务真的同一时刻一起进行。

你会发现,这样一对照,几个概念一下就立住了。

十三、为什么学并发编程前,必须先搞懂这些概念

因为后面你一旦开始学 threading、multiprocessing、asyncio,如果概念没打稳,很容易出现两种情况。

第一种,写代码全靠模仿。

照着教程写,代码能运行,但你不知道自己为什么这样写,也不知道这种方式适合什么问题。

第二种,乱用工具。

本来是网络请求任务,结果用错了方式。 本来是计算密集任务,结果还在指望异步提速。 本来只是一个简单脚本,结果为了追求高级感,硬是加了一堆复杂结构。

最后代码变难维护,性能也没见多大提升。

所以并发编程最重要的,不是先学语法,而是先建立判断力。

你要先知道:

这是等待多,还是计算多 这是适合交替推进,还是适合真正同时执行 这是该用同步,还是该考虑异步

思路对了,后面的技术才有意义。

十四、看一组最简单的感受型代码

先看同步执行:

import timedeftask(name):    print(f"{name} 开始")    time.sleep(2)    print(f"{name} 结束")start = time.time()task("任务1")task("任务2")task("任务3")print("总耗时:", time.time() - start)

这个程序大概率要 6 秒左右。

因为 3 个任务是一个个排队做的。

再看一个伪代码层面的异步思路,你现在不用完全掌握写法,先体会意思就行:

任务1 发起等待任务2 发起等待任务3 发起等待谁先完成,就先处理谁的结果

如果这 3 个任务本质上都主要在等,比如都在等网络响应,那么总耗时就可能接近 2 秒多一点,而不是 6 秒。

注意,这里节省的不是计算时间,而是把原本傻等的时间利用起来了。

这就是为什么异步和并发在 I/O 场景下往往很有价值。

十五、本章你一定要记住的四句话

学完这一章,你至少要把下面四句话记牢。

同步:前面的不结束,后面的不开始。 异步:遇到等待时,不堵着,先去做别的。 并发:多个任务在一段时间内都在推进。 并行:多个任务在同一时刻真的同时执行。

如果这四句话你已经能顺口说出来,说明你的基础已经打下来了。

后面学多线程、多进程、协程时,你会轻松很多。

十六、动手练习

这一章最适合做的练习,不是马上上复杂框架,而是先训练概念判断。

你可以试着判断下面几个场景更接近什么。

场景一:你依次读取 3 个文件,前一个读完才读下一个。 这是同步。

场景二:你发出多个网络请求,在等待返回时去处理别的请求。 这是异步,也形成了并发效果。

场景三:一个 CPU 核心快速切换执行多个任务。 这是并发,不一定是并行。

场景四:4 个 CPU 核心同时处理 4 段独立计算。 这是并行。

再进一步,你可以想想自己以前写过的程序,哪些其实是同步顺序执行,哪些地方如果任务之间互不依赖,就有机会改造成并发处理。

当你开始用这种眼光看代码时,你对程序执行方式的理解就已经升级了。

十七、写在最后

很多初学者一接触并发编程,就急着记模块、背写法、照着教程敲代码。

其实最应该先学的,从来不是工具,而是概念。

因为工具会换,库会更新,写法会变,但背后的执行逻辑不会变。

你只有先明白:

什么叫同步 什么叫异步 什么叫并发 什么叫并行

后面学线程、进程、协程时,才不会每次都像在背天书。

编程里最怕的,不是暂时不会写,而是概念一直模糊。 一旦概念清楚了,代码只是迟早的事。

最新文章

随机文章