• Python多进程


    进程:一个程序的执行实例。对操作系统来说:一个任务就是一个进程。

    线程:一个进程内往往同时运行着多个子任务,这些子任务就是线程。线程是操作系统能够进行运算调度的最小单位。

    一个进程至少有一个线程,一个进程也可以并发多个线程,这些线程可以并行执行不同的任务。一个进程在启动时会先产生一个线程,这个线程被称为主线程,主线程又可以创建其他子线程。

    事件驱动模型:单个进程中单个线程执行多任务的模型。
    协程:单线程的异步编程模型称为协程,可基于事件驱动编写高效的多任务程序。协程又被称为微线程。协程适用于IO密集型的程序中。
    协程的优势:
    1.执行效率极高:程序自身控制子程序切换不是线程切换,因此没有线程切换的开销。
    2.不需要多线程的锁机制,不存在同时写变量冲突,控制共享资源只需判断状态。

    GIL(Global Interpreter Lock): Python标准解释器执行代码时有一个GIL(Global Interpreter Lock)锁,任何Python线程执行前,必须先获得GIL锁,然后,每执行100个字节码,解释器就自动释放GIL锁,让别的线程有机会执行。Python中线程的执行代码都被GIL上了锁,所以Python中多线程只能交替执行,并不能并发执行。Python中实现并发任务一般用多进程。

    Python中的 multiprocessing 模块是跨平台版本的多进程模块

    import os
    from multiprocessing import Process
    
    
    def run_task(param):
        print("run child process: %s (%s)" % (param, os.getpid()))
        
    if __name__ == '__main__':
        print("=====main=====")
    
        p = Process(target=run_task, args=('test',))
        print("用start()方法启动子进程")
        p.start()
        print("join()方法可以等待子进程结束后再继续往下运行")
        p.join()
        print("子进程结束")
    
        print("**********main end**********")
    

    上面程序段的输出为:

    =====main=====
    用start()方法启动子进程
    join()方法可以等待子进程结束后再继续往下运行
    run child process: test (1230)
    子进程结束
    **********main end**********
    

    如果要启动大量的子进程可以用进程池的方式批量创建子进程:

    import os
    import time
    import logging
    from multiprocessing import Pool
    
    logging.basicConfig(level=logging.DEBUG,
                        format="%(asctime)s %(levelname)s %(message)s",
                        datefmt="%H:%M:%S")
    
    
    def getstatusoutput(cmd):
        if cmd == "du -H":
            time.sleep(5)
        pipe = os.popen(cmd, "r")
        text = pipe.read()
        status = pipe.close()
        if status is None:
            status = 0
        if text[-1:] == "
    ":
            text = text[:-1]
        return status
    
    
    def excute_cmd(cmd):
        logging.info("run cmd: %s (%s)" % (cmd, os.getpid()))
        start = time.time()
        if getstatusoutput(cmd) != 0:
            print("run cmd fail")
            return False
        end = time.time()
        logging.info("cmd %s spend %0.2f seconds" % (cmd, (end-start)))
        
        
    if __name__ == '__main__':
        print("=====main=====")
    
        tools = ["ls", "df -H", "du -H"]
        p = Pool(3)
        for cmd in tools:
            p.apply_async(excute_cmd, args=(cmd,))
        print("wait all subprocess done")
        # close()方法必须在join()方法前调用
        p.close()
        # join()方法可以等待子进程结束后再继续往下进行
        p.join()
        print("all subprocess done")
    
        print("**********main end**********")
    

    上面的程序段输出为:

    =====main=====
    wait all subprocess done
    11:47:38 INFO run cmd: ls (1218)
    11:47:38 INFO run cmd: df -H (1219)
    11:47:38 INFO run cmd: du -H (1220)
    11:47:38 INFO cmd df -H spend 0.00 seconds
    11:47:38 INFO cmd ls spend 0.01 seconds
    11:47:43 INFO cmd du -H spend 5.02 seconds
    all subprocess done
    **********main end**********
    

    从输出可以看出三个命令开始执行时间一致:说明是同时执行,所耗时间来看,du -H 比其他命令多了5秒,符合预期。

    本文作者:温茶又折花

    本文链接: https://www.cnblogs.com/dyfblogs/p/14961343.html

    转载文章请注明作者和出处,谢谢!
  • 相关阅读:
    poj2774
    GDOI2012 字符串
    poj3261
    poj1743
    bzoj 2565 manacher
    归档-ios
    学习
    ViewPager动态加载、删除页面
    android:ScrollView嵌套ListView的问题
    Android学习笔记进阶之在图片上涂鸦(能清屏)
  • 原文地址:https://www.cnblogs.com/dyfblogs/p/14961343.html
Copyright © 2020-2023  润新知