前面我们学习了线程,我们也对进程做过相关介绍,学习过线程之后,大家能够知道线程是进程的最小单元,这一节我们就来学习一下如何去创建一个进程,在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. 总结

学习过线程的相关内容之后,进程的内容就显得简单了很多,跟着章节的顺序学习能够提高大家的学习效率。


点赞(0)

C语言网提供由在职研发工程师或ACM蓝桥杯竞赛优秀选手录制的视频教程,并配有习题和答疑,点击了解:

一点编程也不会写的:零基础C语言学练课程

解决困扰你多年的C语言疑难杂症特性的C语言进阶课程

从零到写出一个爬虫的Python编程课程

只会语法写不出代码?手把手带你写100个编程真题的编程百练课程

信息学奥赛或C++选手的 必学C++课程

蓝桥杯ACM、信息学奥赛的必学课程:算法竞赛课入门课程

手把手讲解近五年真题的蓝桥杯辅导课程

Dotcpp在线编译      (登录可减少运行等待时间)