Python创建进程的方式详解

点击打开在线编译器,边学边练

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

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



本文固定URL:https://www.dotcpp.com/course/302

第一章 人生苦短,我用Python
第二章 Python基础语法
第三章 Python入门语法
第四章 Python核心语法
第五章 函数
第六章 面向对象编程
第七章 模块
第八章 异常处理和程序调试
第九章 文件及目录操作
第十章 GUI编程
第十一章 进程和线程
第十二章 数据库管理
第十三章 算法
第十四章 爬虫
第十五章 实战篇
第十六章 后记
Dotcpp在线编译      (登录可减少运行等待时间)