Python中的多进程

1 multiprocessing模块

Python中的多线程无法利用多核优势,如果想要充分利用多核CPU的资源,大部分情况需要使用多进程。
multiprocessing模块可以用来开启子进程,并且提供了许多功能组件,Process,Lock,Queue,Pipe。

2 Process的用法

开启子进程的2种方式

from multiprocessing import Process
import time

def task1(name):
    print("%s 开始执行" % name)
    time.sleep(3)
    print("%s 执行完毕" % name)

if __name__ == '__main__':
    proc=Process(target=task1, args=("进程1",))  #target表示调用对象,及需要执行的任务,注意函数不要加括号,args(元组)表示调用对象的位置参数,还可以加kwargs来通过字典的方式传参
    proc.start() # start方法只是向操作系统发出请求信号,请求操作系统开启一个进程
    print("hahah")
from multiprocessing import Process
import time

class MyProcess(Process): # 继承Process
    def __init__(self,name):
        super().__init__() # 必须调用父类Process的init方法进行初始化,不然会报错
        self.name = name

    def run(self):  # 进程启动时运行的方法,通过此方法调用需要执行的target对应的函数
        print("%s is runing" % self.name)
        time.sleep(3)
        print("%s is done" % self.name)

if __name__ == "__main__":
    p = MyProcess("子进程")
    p.start() # 启动进程,并调用进程中的run()方法
    print("主进程")

查看子进程id和主进程id

from multiprocessing import Process
import time
import os

def task(name,n):
    print("%s is runing " % (name,))
    print("this process id:",os.getpid())
    print("father process id:", os.getppid())
    print("%s is done" % name)
if __name__ == "__main__":
    p = Process(target=task,args=("jack",1),name="子进程1")  # name:为进程取的名字
    p.start()
    print("main process id :",os.getpid()) # 在当前进程中开启一个子进程p,即p是该进程的子进程,所以此处的pid与进程p中的ppid是相同的
main process id : 8148
jack is runing 
this process id: 5760
father process id: 8148
jack is done

join的用法
在主进程运行过程中如果想并发地执行其他的任务,我们可以开启子进程,此时主进程的任务与子进程的任务分两种情况

1:主进程的任务与子进程的任务相互独立,互不干扰,主进程的任务先执行完后,还需要等待子进程执行完毕,然后统一回收资源。

2:如果主进程的任务执行到一半时,需要等待子进程执行完毕后才能继续执行后面的任务,就需要有一种机制能够让主进程检测子进程是否运行完毕,在子进程执行完毕后才继续执行,否则一直在原地阻塞,这时就需要join了

from multiprocessing import Process
import time
import os

def talk(name,n):
    print("%s is talking " % (name,))
    time.sleep(n)
    print("%s is done" % name)
if __name__ == "__main__":
    stime = time.time()
    p1 = Process(target=talk,args=("p1",1))
    p2 = Process(target=talk, args=("p2", 2))
    p3 = Process(target=talk, args=("p3", 3))
    p1.start()
    p2.start()
    p3.start()
    p1.join() 
    p2.join()
    p3.join()
    etime = time.time()
    print(etime-stime)
p1 is talking 
p2 is talking 
p3 is talking 
p1 is done
p2 is done
p3 is done
3.3871939182281494
from multiprocessing import Process
import time
import os

def talk(name,n):
    print("%s is talking " % (name,))
    time.sleep(n)
    print("%s is done" % name)
if __name__ == "__main__":
    stime = time.time()
    for i in range(1,4):
        p = Process(target=talk,args=("p"+str(i),i))
        p.start()
        p.join()
    etime = time.time()
    print(etime-stime)

p1 is talking 
p1 is done
p2 is talking 
p2 is done
p3 is talking 
p3 is done
6.675381660461426

通过上面2个例子,我们可以看出
我们可以通过join方法让主进程等待子进程,直到子进程执行完毕后,再接着执行主进程。注意:是让主进程等待子进程 ,而不是让其他的子进程等待。join([timeout])可以传入一个超时参数,即主进程的等待时间。如果超过该等待时间主进程就不会在等子进程了。
当我们开启一个进程,马上join时,主进程会等该进程执行完毕后再开启下一个进程,这样就变成了串行。

守护进程
守护进程就如字面意思一样,就是守护主进程的,当主进程执行完毕后,守护进程无论时候执行完,都会立即结束。就好比古时候的太监一样,平时辅助皇帝,当皇帝驾崩后,太监也要跟着陪葬。
关于守护进程需要注意2个点:
1 守护进程需要在start()前设置
2 守护进程不能创建子进程

from multiprocessing import Process
import time
import os

def talk(name,n):
    print("%s is talking " % (name,))
    time.sleep(n)
    print("%s is done" % name)
if __name__ == "__main__":
    p = Process(target=talk,args=("p",10))
    p.daemon = True  # 通过p.daemon = True 设置守护进程
    p.start()
    time.sleep(1)
    print("主")

由于p为守护进程,故主进程执行完毕后,p也跟着结束了。所以只输出了p is talking ,而p is done还没来得及输出

p is talking 
主

is_alive()和terminate()
在程序运行的时候,我们可以查看进程是否仍在运行,也可以强制结束进程。

from multiprocessing import Process
import time

def talk(name,n):
    print("%s is talking " % (name,))
    time.sleep(n)
    print("%s is done" % name)
    
if __name__ == "__main__":
    stime = time.time()
    p = Process(target=talk,args=("p",10))
    p.start() #start方法只是向操作系统发出请求信号,请求操作系统开启一个进程
    print(p.is_alive()) # 如果执行速度够快,此时进程可能还没有开启,这里可能返回False也可能返回True
    time.sleep(2)
    print(p.is_alive()) # 经过2秒后操作系统肯定已经开启进程了故此处为True
    time.sleep(2) 
    p.terminate() # 强制结束进程
    etime = time.time()
    print(etime-stime)

执行结果,由于经过2次time.sleep(2)后,将子进程p强制结束了,故程序执行时间最后只有4秒,而没有10秒

True
p is talking 
True
4.023230314254761 
  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值