• Python3的multiprocessing多进程-process模块


    Python3的multiprocessing多进程-process模块

    一、简介

    multiprocessing类似于threading模块支持生成进程的包,是Python的标准模块,它既可以用来编写多进程,也可以用来编写多线程。如果是多线程的话,用multiprocessing.dummy即可,用法与multiprocessing基本相同。

    由于python使用全局解释器锁(GIL),他会将进程中的线程序列化,也就是多核cpu实际上并不能达到并行提高速度的目的,而使用多进程则是不受限的,所以实际应用中都是推荐多进程的。

    如果每个子进程执行需要消耗的时间非常短(执行+1操作等),这不必使用多进程,因为进程的启动关闭也会耗费资源。

    当然使用多进程往往是用来处理CPU密集型(科学计算)的需求,如果是IO密集型(文件读取,爬虫等)则可以使用多线程去处理。

    multiprocessing常用组件及功能

    1.1、管理进程模块:

    • Process(用于创建进程模块)
    • Pool(用于创建管理进程池)
    • Queue(用于进程通信,资源共享)
    • Value,Array(用于进程通信,资源共享)
    • Pipe(用于管道通信)
    • Manager(用于资源共享)

    1.2、同步子进程模块:

    • Condition
    • Event
    • Lock
    • RLock
    • Semaphore

    1.3、Process 类

    class multiprocessing.Process(group=None, target=None, name=None, args=(), kwargs={}, *, daemon=None)

    • Process模块用来创建子进程,是Multiprocessing核心模块,使用方式与Threading类似,可以实现多进程的创建,启动,关闭等操作。
    • 一般需要传入target目标函数,args函数的参数

    (1)run()
           表示进程运行的方法。可以在子类中重写此方法。标准run() 方法调用传递给对象构造函数的可调用对象作为目标参数(如果有),分别使用args和kwargs参数中的顺序和关键字参数。

    (2)start()
           进程准备就绪,等待CPU调度。

    (3)join([ 超时] )
           如果可选参数timeout是None,则该方法将阻塞,直到join()调用其方法的进程终止。如果timeout是一个正数,它最多会阻塞超时秒。请注意,None如果方法的进程终止或方法超时,则返回该方法。检查进程exitcode以确定它是否终止。

    (4)name
           进程的名称。该名称是一个字符串,仅用于识别目的。

    (5)is_alive()
           返回进程是否存活。从start() 方法返回到子进程终止的那一刻,进程对象仍处于活动状态。

    (6)daemon
           进程的守护进程标志,一个布尔值。必须在start()调用之前设置,当进程退出时,它会尝试终止其所有守护进程子进程。

    (7)pid
           返回进程ID。在产生该过程之前,这将是 None。

    (8)exitcode
           子进程的退出代码。None如果流程尚未终止,这将是。负值-N表示孩子被信号N终止。

    需要注意的是start(),join(),is_alive(), terminate()和exitcode方法只能由创建进程对象的过程调用。
    一些方法的示例用法Process:

    from multiprocessing import Process
    import time
    import os
    
    def info():
        print('module name:', __name__)
        print('parent process:', os.getppid())
        print('process id:', os.getpid())
    
    def f(name):
        info()
        time.sleep(3)
        print('hello', name)
    
    if __name__ == '__main__':
        info()
        p = Process(target=f, args=('bob',))
        # p.daemon = False
        print(p.daemon)
        p.start()
        p.join(1)
        print('name:', p.name)
        print('is_alive:', p.is_alive())
        print('exitcode:', p.exitcode)
    '''
    ------------------------------------------------------------
    module name: __main__
    parent process: 1188
    process id: 13060
    False
    module name: __mp_main__
    parent process: 13060
    process id: 13424
    name: Process-1
    is_alive: True
    exitcode: None
    hello bob
    ------------------------------------------------------------
    '''
    在上述逻辑中,子进程会休息3s然后再打印一句话才结束,同时设定join(1)阻塞1s,阻塞在1s后结束,我们的并没有守护主进程,然后主进程结束后,子进程依然alive;
    如果想要守护主进程,设定p.daemon = True:
    if __name__ == '__main__':
        info()
        p = Process(target=f, args=('bob',))
        p.daemon = True
        print(p.daemon)
        p.start()
        # p.join(1)
        print('name:', p.name)
        print('is_alive:', p.is_alive())
        print('exitcode:', p.exitcode)
    '''
    ------------------------------------------------------------
    module name: __main__
    parent process: 1188
    process id: 1668
    True
    name: Process-1
    is_alive: True
    exitcode: None
    ------------------------------------------------------------
    '''
    在上述逻辑中,子进程会休息3s然后再打印一句话才结束,我们的设定守护主进程,然后主进程结束后,打印的is_alive: True这句话其实是在主进程里运行的,所以此时子进程确实是alive,但是主进程结束后子进程也结束了,不会运行info() 函数;
  • 相关阅读:
    设计模式之单例模式
    常用正则表达式
    前台页面json格式数据中文显示问号
    关于SpringMVC中静态资源配置问题
    Tomcat 9启动后控制台中文输出乱码问题
    SpringAOP中 order属性问题
    避坑!Mybatis Generator 生成文件的时候错误使用了其它数据库的同名数据表(关于nullCatalogMeansCurrent参数)
    关于JDBC中 Statement 和 PreparedStatement的区别
    关于Class.newInstance()方法被弃用
    Celery
  • 原文地址:https://www.cnblogs.com/lizm166/p/14658294.html
Copyright © 2020-2023  润新知