前面我们学习了线程,我们也对进程做过相关介绍,学习过线程之后,大家能够知道线程是进程的最小单元,这一节我们就来学习一下如何去创建一个进程,在Python中给我们提供了多个模块去创建进程,常用的有multiprocessing模块、os.fork()函数和Pool进程池,这三种方式中,os.fork只能在Linux、mac和UNIX系统使用,不可在windows中使用,而multiprocessing和pool进程池都是跨平台的,本节我们主要来学习一下multiprocessing模块。
1. multiprocessing模块
Multiprocessing模块主要复制线程模块的API,为我们提供一个Process类来创建进程对象,它的语法格式为:
Process(group=None,target=None,name=None,args=(),kwargs={},daemon=None)
group总是为None,它只与线程兼容 ,target是run()方法要调用的可调用对象,默认为“无”,即不调用任何内容。name是进程名。args是目标调用的参数元组。kwargs是目标调用的关键字参数字典,如果提供,关键字only daemon参数会将进程守护程序标志设置为True或False。如果没有(默认),则此标志将从创建过程继承。
我们通过Process类来创建一个进程,代码如下:
import multiprocessing def process(): print('创建了一个子进程') if __name__ == '__main__': print('主进程开始') process_one = multiprocessing.Process(target = process,args = ()) process_one.start() print('主进程完成')
运行结果如下:
主进程开始 主进程完成 创建了一个子进程
创建进程的方式和创建线程的方式大体一致,创建完成后都是通过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子类中的方法来创建子进程,大家可以尝试模仿着线程的创建方式去创建一个子进程。
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())
输出结果为:
父进程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. 总结
学习过线程的相关内容之后,进程的内容就显得简单了很多,跟着章节的顺序学习能够提高大家的学习效率。
C语言网提供由在职研发工程师或ACM蓝桥杯竞赛优秀选手录制的视频教程,并配有习题和答疑,点击了解:
一点编程也不会写的:零基础C语言学练课程
解决困扰你多年的C语言疑难杂症特性的C语言进阶课程
从零到写出一个爬虫的Python编程课程
只会语法写不出代码?手把手带你写100个编程真题的编程百练课程
信息学奥赛或C++选手的 必学C++课程
蓝桥杯ACM、信息学奥赛的必学课程:算法竞赛课入门课程
手把手讲解近五年真题的蓝桥杯辅导课程