关于进程中 apply()和apply_async()的区别

apply():
apply是阻塞的。首先主进程开始运行,碰到子进程,操作系统切换到子进程,等待子进程运行结束后,在切换到另外一个子进程,直到所有子进程运行完毕。然后在切换到主进程,运行剩余的部分。这样跟单进程串行执行没什么区别。

如:

import time
from multiprocessing import Pool


def run(count):
  print('子进程编号:%s' % count)
  time.sleep(2)
  print('子进程%s结束' % count)


if __name__ == "__main__":
  print("开始执行主进程")
  start_time = time.time()
  # 使用进程池创建子进程
  pool = Pool(4)
  print("开始执行子进程")
  for i in range(4):
    pool.apply(run, (i,))
  print("主进程结束,总耗时%s" % (time.time() - start_time))
运行结果如下:

开始执行主进程
开始执行子进程
子进程编号:0
子进程0结束
子进程编号:1
子进程1结束
子进程编号:2
子进程2结束
子进程编号:3
子进程3结束
主进程结束,总耗时8.678496360778809
可以看到子进程是顺序执行的,且子进程全部执行完毕后才继续执行主进程。

apply_async():
apply_async 是异步非阻塞的。即不用等待当前进程执行完毕,随时根据系统调度来进行进程切换。首先主进程开始运行,碰到子进程后,主进程仍可以先运行,等到操作系统进行进程切换的时候,在交给子进程运行。可以做到不等待子进程执行完毕,主进程就已经执行完毕,并退出程序。

如:

import time
from multiprocessing import Pool


def run(count):
  print('子进程编号:%s' % count)
  time.sleep(2)
  print('子进程%s结束' % count)


if __name__ == "__main__":
  print("开始执行主程序")
  start_time = time.time()
  # 使用进程池创建子进程
  pool = Pool(4)
  print("开始执行子进程")
  for i in range(4):
    pool.apply_async(run, (i,))
  print("主进程结束耗时%s" % (time.time() - start_time))
运行结果如下:

开始执行主程序
开始执行子进程
主进程结束耗时0.06800413131713867
进程的切换是操作系统来控制的,是抢占式的切换。 我们首先运行的是主进程,由于主进程代码很简单,主进程一下子就运行完毕了,所以子进程完全没有机会切换到程序就已经结束了。

如果我们想要子进程执行完毕后再运行主进程剩余部分,则在恰当位置上加上一句子进程名.join()。这样就告诉主进程等该子进程执行完毕后,再运行主进程剩余部分。

如:

import time
from multiprocessing import Pool


def run(count):
  print('子进程编号:%s' % count)
  time.sleep(2)
  print('子进程%s结束' % count)


if __name__ == "__main__":
  print("开始执行主程序")
  start_time = time.time()
  # 使用进程池创建子进程
  pool = Pool(4)
  print("开始执行子进程")
  for i in range(4):
    pool.apply_async(run, (i,))
  pool.close()
  pool.join()
  # 进程池调用close方法后,会把进程池状态改为不可再插入元素的状态,但并未关闭进程池
  # close必须在join之前调用。
  # join()调用后主进程必须等子进程全部运行结束后才接着运行主进程。
  print("主进程结束耗时%s" % (time.time() - start_time))
  注意:

  close必须在join前调用。

运行结果如下:

开始执行主程序
开始执行子进程
子进程编号:0
子进程编号:1
子进程编号:2
子进程编号:3
子进程0结束
子进程1结束
子进程2结束
子进程3结束
主进程结束耗时2.852163314819336
python官方建议:废弃apply,尽量使用apply_async。
---------------------
作者:一骑走烟尘
来源:CSDN
原文:https://blog.csdn.net/zgcr654321/article/details/82845083
版权声明:本文为博主原创文章,转载请附上博文链接!

原文地址:https://www.cnblogs.com/xiaoxiaoshuaishuai0219/p/9874830.html