学习了线程,我们也对进程做过相关介绍,学习过线程之后,大家能够知道线程是进程的最小单元,这一节我们就来学习一下如何去创建一个进程,在Python中给我们提供了多个模块去创建进程,常用的有multiprocessing模块、os.fork()函数和Pool进程池,这三种方式中,os.fork只能在Linux、mac和UNIX系统使用,不可在windows中使用,而multiprocessing和pool进程池都是跨平台的,本节我们主要来学习一下multiprocessing模块。
1. multiprocessing模块
Multiprocessing模块主要复制线程模块的API,为我们提供一个Process类来创建进程对象,它的语法格式为:
1 | Process(group = None ,target = None ,name = None ,args = (),kwargs = {},daemon = None ) |
group总是为None,它只与线程兼容 ,target是run()方法要调用的可调用对象,默认为“无”,即不调用任何内容。name是进程名。args是目标调用的参数元组。kwargs是目标调用的关键字参数字典,如果提供,关键字only daemon参数会将进程守护程序标志设置为True或False。如果没有(默认),则此标志将从创建过程继承。
我们通过Process类来创建一个进程,代码如下:
12345678 | import multiprocessing def process(): print ( '创建了一个子进程' ) if __name__ = = '__main__' : print ( '主进程开始' ) process_one = multiprocessing.Process(target = process,args = ()) process_one.start() print ( '主进程完成' ) |
运行结果如下:
123 | 主进程开始 主进程完成 创建了一个子进程 |
创建进程的方式和创建线程的方式大体一致,创建完成后都是通过start()函数来使用,除了start(),还有一些方法供我们使用:
1) run()
表示进程活动的方法,我们在前面提到线程中也使用了这种方法。
2) join([timeout])
如果可选参数timeout为None(默认值),则方法将阻塞,直到调用其join()方法的进程终止。如果timeout是正数,则它最多阻塞超时秒数。请注意,如果方法的进程终止或方法超时,则该方法将返回None。检查进程的退出代码以确定它是否终止。
3) is_alive()
返回进程是否活动。
4) terminate()
终止进程,在Unix上,这是使用SIGTERM信号完成的;在Windows上,使用TerminateProcess(),退出处理程序和最后子句等将不会被执行。
5) Close()
关闭流程对象,释放与之关联的所有资源。如果基础进程仍在运行,则引发ValueError。一旦close()成功返回,Process对象的大多数其他方法和属性都将引发ValueError。
6) kill()
和terminate() 类似,但在Unix上使用SIGKILL信号。
7) Pid
返回进程ID。
2. 使用Process子类创建进程
我们在前面学习线程的时候学习了使用Thread子类创建线程,进程和线程一样可以通过Process子类中的方法来创建子进程,大家可以尝试模仿着线程的创建方式去创建一个子进程。
123456789101112131415161718192021 | import multiprocessing import time import datetime import os class MyProcess(multiprocessing.Process): def __init__( self ,name = None ): #使用父类中的初始化方法 multiprocessing.Process.__init__( self ) #接受参数 if name: #判断传递的参数是否存在 self .name = name def run( self ): print ( '子进程开始的时间为:' ,datetime.datetime.now()) print ( '子进程%s正在执行' % os.getpid()) time.sleep( 5 ) print ( '子进程执行完毕的结束时间为' , datetime.datetime.now()) if __name__ = = '__main__' : print ( '父进程PID为' ,os.getpid()) print ( '父进程开始执行的时间为:' ,datetime.datetime.now()) process_one = MyProcess() process_one.start() #启动进程 process_one.join() #等待进程执行结束 print ( '父进程结束执行的时间为:' ,datetime.datetime.now()) |
输出结果为:
123456 | 父进程PID为 12424 父进程开始执行的时间为: 2020 - 02 - 09 19 : 52 : 36.045122 子进程开始的时间为: 2020 - 02 - 09 19 : 52 : 36.145852 子进程 924 正在执行 子进程执行完毕的结束时间为 2020 - 02 - 09 19 : 52 : 41.146354 父进程结束执行的时间为: 2020 - 02 - 09 19 : 52 : 41.155225 |
我们在这个例子中引入了时间模块,我们可以通过时间来观察父进程和子进程的关系,使用Process子类创建子进程的方式基本上和创建线程的一样,同样要注意join()的使用,不使用join()方法的时候主线程会提前结束,这一点我们可以通过注释掉 process_one.join()去观察一下。
3. 总结
学习过线程的相关内容之后,进程的内容就显得简单了很多,跟着章节的顺序学习能够提高大家的学习效率。