zoukankan      html  css  js  c++  java
  • 关于进程中 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
    版权声明:本文为博主原创文章,转载请附上博文链接!

  • 相关阅读:
    mysql用户密码修改
    Java List java.lang.UnsupportedOperationException
    python __dict__
    pytest.fixture
    Python __metaclass__ 解释
    Python __new__()方法,为对象分配内存 返回对象的引用
    git 常用操作
    boto3 dynamodb 一些简单操作
    conda, pip, virtualenv 区别
    list去重后不改变排序
  • 原文地址:https://www.cnblogs.com/xiaoxiaoshuaishuai0219/p/9874830.html
Copyright © 2011-2022 走看看