Python多进程

时间:2021-07-02 15:54:52   收藏:0   阅读:0

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

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

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

事件驱动模型:单个进程中单个线程执行多任务的模型。
协程:单线程的异步编程模型称为协程,可基于事件驱动编写高效的多任务程序。协程又被称为微线程。协程适用于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:] == "\n":
        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秒,符合预期。

评论(0
© 2014 mamicode.com 版权所有 京ICP备13008772号-2  联系我们:gaon5@hotmail.com
迷上了代码!