并发编程之同步异步
同步异步
阻塞:进程遇到IO操作,导致任务无法继续执行其他代码,称为阻塞。
非阻塞:程序在正常运行没有遇到IO操作,或者通过某种方式使程序即时遇到了也不会停在原地,还可以执行其他操作,以提高CPU的占用率
阻塞、非阻塞:指程序的运行状态
并行、并发、串行:处理任务的方式
同步:提交任务后需要在原地等待,直到任务继续执行,效率低。
def task():
for i in range(100000000):
1+1
print("start")
task() # 卡住了,但是不是阻塞,而是在进行大量的计算
print("over")
# 此时程序执行到task()函数时,程序没有阻塞;同时主进程能够知道这个代码什么时候能执行完毕,这样的情况我们成为同步
异步:提交任务后不需要在原地等待,可以继续往下执行代码,效率比同步要高
import multiprocessing
def task():
for i in range(100000000):
1+1
if __name__ == '__main__':
print("start")
p = multiprocessing.Process(target=task) # 执行task之后,
p.start()
print("over")
PS:同步会有等待的效果但是这和阻塞是完全不同的,阻塞时程序会被剥夺CPU执行权,而同步调用则不会!
问题:
异步效率高于同步,但是异步会导致任务发起方不知道任务何时完毕
解决方法:
- 轮询,重复的隔一段时间就问一次,消耗资源
- 让任务完成后,通知调用方,我们也称为:异步回调
异步回调:
import multiprocessing
def task(func):
for i in range(100000000):
1+1
func("OK")
def finish(a):
'''需要对结果进行处理,所以此处可以写上处理结果的代码逻辑'''
print("程序完成",a)
if __name__ == '__main__':
print("start")
p = multiprocessing.Process(target=task,args=(finish,)) # 执行task之后,
p.start()
print("over")
好处:经过这样处理之后,我们可以在finish函数中拿到对应的结果,然后在finish增加对结果的处理逻辑,这样就达到了我们的目的