• 为了保证你在浏览本网站时有着更好的体验,建议使用类似Chrome、Firefox之类的浏览器~~
    • 如果你喜欢本站的内容何不Ctrl+D收藏一下呢,与大家一起分享各种编程知识~
    • 本网站研究机器学习、计算机视觉、模式识别~当然不局限于此,生命在于折腾,何不年轻时多折腾一下

python多进程multiprocess理解

Python admin 3个月前 (04-21) 185次浏览 0个评论 扫描二维码

目前的工作任务大部分都是在基于分布式操作,前提是当前这个任务可以分布式操作,如果不可以的话也得通过单机操作,单机操作为了更好的利用机器的资源,适当使用多进程或者多线层可以一定程度上提升计算效率。大家都知道 python 存在 GIL 全局锁,所以多线程并不是真的多线程,每次实际上只有一个线程在运作。这个只是一般意义上的说法,比如遇到文件 IO 读写,GIL 全局锁是可以被释放的,这样的话也是真的多线程。

multiprocessing 支持子进程、通信和共享数据、执行不同形式的同步,提供了 Process、Queue、Pipe、Lock 等组件。

1. Process

创建进程的类:Process([group [, target [, name [, args [, kwargs]]]]]),target 表示调用对象,args 表示调用对象的位置参数元组。kwargs 表示调用对象的字典。name 为别名。group 实质上不使用。
方法:is_alive()、join([timeout])、run()、start()、terminate()。其中,Process 以 start()启动某个进程。

属性:authkey、daemon(要通过 start()设置)、exitcode(进程在运行时为 None、如果为–N,表示被信号 N 结束)、name、pid。其中 daemon 是父进程终止后自动终止,且自己不能产生新进程,必须在 start()之前设置。

例 1.1:创建函数并将其作为单个进程

import multiprocessing
import time

def worker(interval):
    n = 5
    while n > 0:
        print("The time is {0}".format(time.ctime()))
        time.sleep(interval)
        n -= 1

if __name__ == "__main__":
    p = multiprocessing.Process(target = worker, args = (3,))#启动一个进程成型 worker 这个函数
    p.start()
    print "p.pid:", p.pid  #我们可以在运行的进程里面根据 pid 找到
    print "p.name:", p.name
    print "p.is_alive:", p.is_alive() #判断这个进程是否还存在

结果

p.pid: 8736
p.name: Process-1
p.is_alive: True
The time is Tue Apr 21 20:55:12 2015
The time is Tue Apr 21 20:55:15 2015
The time is Tue Apr 21 20:55:18 2015
The time is Tue Apr 21 20:55:21 2015
The time is Tue Apr 21 20:55:24 2015

 

例 1.2:创建函数并将其作为多个进程

import multiprocessing
import time

def worker_1(interval):
    print "worker_1"
    time.sleep(interval)
    print "end worker_1"

def worker_2(interval):
    print "worker_2"
    time.sleep(interval)
    print "end worker_2"

def worker_3(interval):
    print "worker_3"
    time.sleep(interval)
    print "end worker_3"

if __name__ == "__main__":
    p1 = multiprocessing.Process(target = worker_1, args = (2,)) #创建多个进程
    p2 = multiprocessing.Process(target = worker_2, args = (3,))
    p3 = multiprocessing.Process(target = worker_3, args = (4,))

    p1.start()#进程的启动都是需要通过 start 函数来启动,执行结束后自动终止
    p2.start()
    p3.start()

    print("The number of CPU is:" + str(multiprocessing.cpu_count()))
    for p in multiprocessing.active_children():
        print("child   p.name:" + p.name + "\tp.id" + str(p.pid))
    print "END!!!!!!!!!!!!!!!!!"

结果

The number of CPU is:4
child   p.name:Process-3	p.id7992
child   p.name:Process-2	p.id4204
child   p.name:Process-1	p.id6380
END!!!!!!!!!!!!!!!!!
worker_1
worker_3
worker_2
end worker_1
end worker_2
end worker_3

 

例 1.3:将进程定义为类

import multiprocessing
import time

class ClockProcess(multiprocessing.Process):
    def __init__(self, interval):
        multiprocessing.Process.__init__(self)
        self.interval = interval

    def run(self):
        n = 5
        while n > 0:
            print("the time is {0}".format(time.ctime()))
            time.sleep(self.interval)
            n -= 1

if __name__ == '__main__':
    p = ClockProcess(3)
    p.start()#在调用 start 函数的时候,会主动调用类内部函数 run

:进程 p 调用 start()时,自动调用 run()

结果

the time is Tue Apr 21 20:31:30 2015
the time is Tue Apr 21 20:31:33 2015
the time is Tue Apr 21 20:31:36 2015
the time is Tue Apr 21 20:31:39 2015
the time is Tue Apr 21 20:31:42 2015

 

例 1.4:daemon 程序对比结果

#1.4-1 不加 daemon 属性

daemon 是守护进程的意思,大致可以这么理解,比如主进程 fork 一个子进程出来,然后立即杀掉这个主进程,子进程仍然不受影响

import multiprocessing
import time

def worker(interval):
    print("work start:{0}".format(time.ctime()));
    time.sleep(interval)
    print("work end:{0}".format(time.ctime()));

if __name__ == "__main__":
    p = multiprocessing.Process(target = worker, args = (3,))
    p.start()
    print "end!"

结果

end!
work start:Tue Apr 21 21:29:10 2015
work end:Tue Apr 21 21:29:13 2015

#1.4-2 加上 daemon 属性

import multiprocessing
import time

def worker(interval):
    print("work start:{0}".format(time.ctime()));
    time.sleep(interval)
    print("work end:{0}".format(time.ctime()));

if __name__ == "__main__":
    p = multiprocessing.Process(target = worker, args = (3,))
    p.daemon = True#设置了 daemon 属性,但是主进程执行完之后程序就运行结束了,那么子进程当然也会结束啦,而且子进程是不会占用交互命令行
    p.start()
    print "end!"

结果

end!

:因子进程设置了 daemon 属性,主进程结束,它们就随着结束了。

#1.4-3 设置 daemon 执行完结束的方法

import multiprocessing
import time

def worker(interval):
    print("work start:{0}".format(time.ctime()));
    time.sleep(interval)
    print("work end:{0}".format(time.ctime()));

if __name__ == "__main__":
    p = multiprocessing.Process(target = worker, args = (3,))
    p.daemon = True
    p.start()
    p.join()#调用了 join 之后,表示主进程要等其他进程运行结束后才结束
    print "end!"

结果

work start:Tue Apr 21 22:16:32 2015
work end:Tue Apr 21 22:16:35 2015
end!

 


Deeplearn, 版权所有丨如未注明 , 均为原创丨本网站采用BY-NC-SA协议进行授权 , 转载请注明python 多进程 multiprocess 理解
喜欢 (0)
admin
关于作者:

您必须 登录 才能发表评论!