Python协程异步与同步机制详解及代码对比
本文通过Python代码示例,深入解析同步与异步、阻塞与非阻塞的核心区别。利用gevent、多线程及多进程对比执行效率,结合生活化比喻阐明异步IO的优势,帮助开发者理解协程在提升程序性能中的作用。
以下代码分别采用协程、多线程和多进程三种方式运行,直观展示异步操作与同步操作的执行差异。
import gevent
import threading
import multiprocessing
# 这里展示同步和异步的性能区别,可以看到异步直接同时执行并完成,
# 而同步,需要等待第一个完成后再次执行下一个,是有顺序的执行,而异步不需要
import time
def task(pid):
gevent.sleep(0.5)
print('Task %s done' % pid)
def task2(pid):
time.sleep(0.5)
print('Task %s done'%pid)
def synchronous():
for i in range(1, 10):
task(i)
def asynchronous():
threads = [gevent.spawn(task, i) for i in range(1,10)]
gevent.joinall(threads)
def thread_chronous():
t_list = []
for i in range(1,10):
t = threading.Thread(target=task2,args=(i,))
t.start()
t_list.append(t)
for j in t_list:
j.join()
def multi_chronous():
t_list = []
for i in range(1, 10):
t = multiprocessing.Process(target=task2, args=(i,))
t.start()
t_list.append(t)
for j in t_list:
j.join()
# 同步执行
print('Synchronous:')
synchronous()
# 开启协程异步执行 自动切换函数
print('Asynchronous:')
asynchronous()
# 开启线程异步执行
print('Threading')
thread_chronous()
# 开启进程的异步执行
if __name__ == '__main__':
print('Multiprocess')
multi_chronous()
对于异步与同步概念的一些理解:
同步与异步的核心区别在于是否等待IO操作的结果。以在麦当劳点餐为例,若你点了一个汉堡,被告知需要现做并等待5分钟,你必须站在收银台前等待直至拿到汉堡,随后才能去逛商场,这种模式属于同步IO。
若点汉堡时被告知需等待5分钟,但你可以先离开去逛商场,待汉堡做好后商家通知你,此时你可以立即去处理其他事务,这种模式属于异步IO。
假设老张爱喝茶,废话少说,直接煮开水。涉及人物有老张以及两把水壶:一把普通水壶(简称水壶)和一把会响的水壶(简称响水壶)。
情形1:老张将水壶放在火上,原地等待水开(同步阻塞)。老张自感这种做法有些傻。
情形2:老张将水壶放在火上,去客厅看电视,并时不时去厨房查看水是否开了(同步非阻塞)。老张仍觉得有些傻,于是升级装备,买了一把会响笛的水壶。水开后,水壶会发出响亮的嘀声。
情形3:老张将响水壶放在火上,原地等待水开(异步阻塞)。老张认为这样干等没有意义。
情形4:老张将响水壶放在火上,去客厅看电视,在水壶响之前不再查看,听到响声后再去拿壶(异步非阻塞)。老张觉得自己变得聪明了。所谓同步与异步,是相对于水壶而言的。普通水壶执行同步操作;响水壶执行异步操作。虽然两者都能烧水,但响水壶能在完工后主动提示老张水已烧开,这是普通水壶无法做到的。同步模式下,调用者只能轮询自身状态(如情形2),导致老张效率低下。所谓阻塞与非阻塞,是相对于老张而言的。原地等待的老张处于阻塞状态;看电视的老张处于非阻塞状态。在情形1和情形3中,老张都是阻塞的,甚至媳妇喊他都没反应。尽管情形3中的水壶是异步的,但对于原地等待的老张而言意义不大。因此,异步通常与非阻塞配合使用,这样才能充分发挥异步的优势。
以上关于Python协程中异步与同步区别的详解内容分享完毕,希望能为读者提供参考,并欢迎大家继续支持本站。
免责声明:本文内容仅供参考,不代表本站观点。转载或引用请注明出处。









