Python进阶教程m11–多进程

原文链接: http://www.juzicode.com/python-tutorial-multiprocess/

Python进阶教程m10–多线程Python进阶教程m10b–多线程通信 我们介绍了多线程编程,并行编程模式中还有一种多进程编程模式,这篇文章将介绍到多进程编程。

1、编程模型

多进程需要用到multiprocessing模块,多进程编程模型可以参考多线程模型。 通过一个例子我们先来看下多进程的基本编程模型,在这个例子中主进程定义和开启了一个子进程,在子进程中打印自己的进程名称和循环次数,循环次数达到上限后退出子进程:

import os,time, multiprocessing

def func1():
    proc_name = multiprocessing.current_process().name
    proc_id = os.getpid()
    print('进入进程:  pid = ', proc_id,' name=',proc_name)
    print('父进程id:  ', os.getppid())
    loopcnt = 0
    while loopcnt < 10:
        loopcnt = loopcnt + 1
        print('进程: %s, loopcnt=%d' % (proc_id, loopcnt))
        time.sleep(0.3)
    print('退出进程:  ' , proc_id)

if __name__ == '__main__':
    print('\n-----欢迎来到www.juzicode.com')
    print('-----公众号: 桔子code/juzicode \n')   
    proc_name = multiprocessing.current_process().name
    proc_id = os.getpid()
    print('进入主进程:  pid = ', proc_id,' name=',proc_name)
    p1 = multiprocessing.Process(target=func1, name='func1')
    p1.start()
    #p1.join()
    time.sleep(5)
    print('退出主进程: ' ,proc_id)
========运行结果:
-----欢迎来到www.juzicode.com
-----公众号: 桔子code/juzicode

进入主进程:  pid =  13692  name= MainProcess
进入进程:  pid =  26540  name= func1
父进程id:   13692
进程: 26540, loopcnt=1
进程: 26540, loopcnt=2
进程: 26540, loopcnt=3
进程: 26540, loopcnt=4
进程: 26540, loopcnt=5
进程: 26540, loopcnt=6
进程: 26540, loopcnt=7
进程: 26540, loopcnt=8
进程: 26540, loopcnt=9
进程: 26540, loopcnt=10
退出进程:   26540
退出主进程:  13692

从上面的例子可以看出多进程编程的基本模型和多线程是一样的:首先定义一个或多个任务函数,这个例子中定义了一个func1任务(函数);在主线程中用multiprocessing.Process()定义了这个任务的实例p1;然后使用 p1.start()启动func1任务。 注意在 Process (target=func1, name=’func1′)定义任务实例时,target入参是函数名称func1,而不是执行函数“func1()”的写法,是不带“()”符号的

2、multiprocessing、进程对象的属性方法

2.1、 multiprocessing 属性、方法

通过multiprocessing 的属性和方法可以获取线程列表、活动线程数、线程ID等:

multiprocessing .active_children()获取活动子进程对象返回包含子进程对象的list
multiprocessing .current_process()返回当前进程对象该对象下的name属性可以获取到当前进程的名称

多进程没有类似多线程get_ident()获取线程id的方法,但是可以使用os.getpid()获取该进程的编号,使用os.getppid()获取父进程的编号。

2.2、进程对象的属性、方法

通过multiprocessing.Process()创建的线程对象常用的属性、方法有:

is_alive()判断进程程对象是否是活动的在使用start()启动线程前和线程结束后,调用该方法返回False
name进程对象名称仅仅用来标识,可以不是唯一的
start()开启进程进程创建后只是创建了对象,需要使用start()方法开启进程。
join()等待进程结束调用者会被阻塞,直到被启动进程结束,如果被启动进程中使用无限循环时需要小心

multiprocessing、进程对象的属性方法的一个例子:


import os,time, multiprocessing

def func1():
    proc_name = multiprocessing.current_process().name
    proc_id = os.getpid()
    print('进入进程:  pid = ', proc_id,' name=',proc_name)
    print('父进程id:  ', os.getppid())
    loopcnt = 0
    while loopcnt < 5:
        loopcnt = loopcnt + 1
        print('进程: %s, loopcnt=%d' % (proc_id, loopcnt))
        time.sleep(0.2)
    print('退出进程:  ' , proc_id)

    
if __name__ == '__main__':
    print('\n-----欢迎来到www.juzicode.com')
    print('-----公众号: 桔子code/juzicode \n')   
    proc_name = multiprocessing.current_process().name
    proc_id = os.getpid()
    print('进入主进程:  pid = ', proc_id,' name=',proc_name)
    print('主进程的父进程id:  ', os.getppid())    
    p1 = multiprocessing.Process(target=func1, name='func1')
    p2 = multiprocessing.Process(target=func1, name='func2')
    p1.start()
    p2.start()
    print('子进程1的名称:',p1.name)
    print('子进程2的名称:',p2.name)
    print('当前活动子进程数:', multiprocessing.active_children())
    print('子进程1是否存活:',p1.is_alive())
    print('子进程2是否存活:',p2.is_alive())
    time.sleep(5)
    print('主进程延时5s后:')
    print('子进程1是否存活:',p1.is_alive())
    print('子进程2是否存活:',p2.is_alive())    
    print('退出主进程: ' ,proc_id)
==========运行结果:
-----欢迎来到www.juzicode.com
-----公众号: 桔子code/juzicode

进入主进程:  pid =  3868  name= MainProcess
主进程的父进程id:   10264
子进程1的名称: func1
子进程2的名称: func2
当前活动子进程数: [<Process name='func2' pid=21616 parent=3868 started>, <Process name='func1' pid=9796 parent=3868 started>]
子进程1是否存活: True
子进程2是否存活: True
进入进程:  pid =  21616  name= func2
父进程id:   3868
进程: 21616, loopcnt=1
进入进程:  pid =  9796  name= func1
父进程id:   3868
进程: 9796, loopcnt=1
进程: 21616, loopcnt=2
进程: 9796, loopcnt=2
进程: 21616, loopcnt=3
进程: 9796, loopcnt=3
进程: 21616, loopcnt=4
进程: 9796, loopcnt=4
进程: 21616, loopcnt=5
进程: 9796, loopcnt=5
退出进程:   21616
退出进程:   9796
主进程延时5s后:
子进程1是否存活: False
子进程2是否存活: False
退出主进程:  3868
 

3、创建进程的其他参数

args、kwargs、daemon等入参的功能和用法参照 Python进阶教程m10–多线程

4、多进程通信

多进程通信也可以使用 Manager、Pipe、Event、Lock 等并行编程工具包,使用方法参照 Python进阶教程m10b–多线程通信

推荐阅读:
Python进阶教程m10–多线程 
Python进阶教程m10b–多线程通信  

发表评论

您的电子邮箱地址不会被公开。 必填项已用*标注