当前位置 博文首页 > zy010101博客:Python多进程

    zy010101博客:Python多进程

    作者:[db:作者] 时间:2021-06-12 09:33

    在python中有一个multiprocessing的模块,该模块提供了一个Process类创建进程对象。因此,需要使用多进程的时候,需要导入这个包。如下:

    from multiprocessing import Process    #导入模块

    下面是一个例子,非常简单。注释里面写的也是非常清楚的。

    from multiprocessing import Process     #导入多进程模块
    
    def child1():        #实现子进程功能的函数
        print("子进程")
    
    def child2(num):
        print(num)
    
    def child3(num,age):
        print(num,age)
    
    if __name__ == "__main__":      #这行语句在Windows下执行python多进程的时候必须加上,Linux可以不需要。
        '''
        在Windows下子进程会自动import启动它的文件,这就导致,在Windows下如果不加这句,那么子进程会循环创建它本身,导致子进程出现问题。
        所以,创建子进程的语句必须被这个if给包含起来。这也意味着程序会从这里开始执行。
        __name__ 是属于 python 中的内置类属性,就是它会天生就存在于一个 python 程序中,代表对应程序名称。
        当我们在运行这个代码时这个代码的 __name__ 的值为 __main__
        当自己作为模块被调用时就是自己的名字
        '''
    
        p1 = Process(target=child1,name="简单的进程")       #创建进程对象,target参数是指定实现子进程功能的函数;name参数是指定子进程名字。
        p2 = Process(target=child2,name="打印数字进程",args=(123,))     #args参数的内容将会被传递给target指定的函数。注意args是一个元组。当你只有一个参数的时候,那么需要加上逗号。
        p3 = Process(target=child3,name="多参数子进程",args=(456,18))   
    
        p1.start()   #启动子进程,把进程加入到就绪队列中,等待系统调度机制来调用该进程。
        p2.start()
        p3.start()
    
        p1.join()    #父进程等待子进程结束,如果不使用join(),那么父进程将不会等待子进程。
        p2.join()       #join还有一个timeout参数,可以设置等待子进程的时长。
        p3.join()
    
        #进程名称对于程序员而言是有用的,但是对于操作系统而言是无意义的,操作系统用来唯一标识一个进程的标志是pid
        print(p1.name)   #打印子进程名字。
        print(p2.name)  
        print(p3.name)
    
        print(p1.pid)   #打印pid
        print(p2.pid)
        print(p3.pid)

    执行程序结果如下:

    ?

    Python的全局变量在多个进程中是不共享的,进程之间的数据是独立的。这也符合进程这个概念。下面来看一个例子。

    from multiprocessing import Process
    
    num = 0
    def child1():
        global num      #global表明使用全局的num变量
        num = -1
        print(num)
    
    def child2():
        global num
        num = 1
        print(num)
    
    if __name__ == "__main__":
        p1 = Process(target=child1,name="child1")
        p2 = Process(target=child2,name="child2")
        
        p1.start()
        p2.start()
        
        p1.join()
        p2.join()
    
        print(num)

    执行结果如下:

    当然了,你也可以继承Process类来实现自己的进程类,从而实现多进程。例如下面的例子:

    from multiprocessing import Process
    
    class MyProcess(Process):
        def run(self):
            print("这是新进程")
    
    if __name__ == "__main__":
        p = MyProcess()
        p.start()

    需要说明的是,当你继承Process类之后,必须重写run函数,而run函数制作的内容就是你子进程执行的代码,start()函数会去调用run函数,从而启动一个新的进程。当你需要参数的时候,那么这个类需要一个自定义的初始化函数__init__()。

    Python的multiprocessing模块还提供了Pool来创建进程池,它能方便我们创建十几个或者上百个进程。

    from multiprocessing import Pool
    import time
    
    def task(num):
        print(num)
        time.sleep(3)
    
    if __name__ == "__main__":
        p = Pool(5)     #创建进程池,并切并发5个进程。
        for i in range(30):         #循环创建30个进程,但是每次只同时并发5个进程。
            p.apply_async(task, args=(i,))      
        
        print("等待结束")
        p.close()       #关闭进程池
        p.join()        #join必须放在close后面。
        print("结束")

    ?

    ?

    下一篇:没有了