zoukankan      html  css  js  c++  java
  • 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

    转载文章请注明作者和出处,谢谢!
  • 相关阅读:
    未能正确加载“Microsoft.VisualStudio.Editor.Implementation.EditorPackage”
    未能正确加载“Microsoft.VisualStudio.Editor.Implementation.EditorPackage”包
    重装VS2010时出现未能正确加载 "radlangsvc.package,radlangsvc.vs...
    page.Response.WriteFile(newpath);
    Response.ContentType 详细列表 <转>
    创建存储过程,使用游标更新表信息
    淘宝顶端的通知样式 .
    ssm整合各配置文件
    XSS-Labs(Level1-10)
    局域网技术
  • 原文地址:https://www.cnblogs.com/dyfblogs/p/14961343.html
Copyright © 2011-2022 走看看