python 多进程

Posted fushuanglin

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了python 多进程相关的知识,希望对你有一定的参考价值。

multiprocessing 模块介绍

python中的多线程无法利用多核优势,如果想要充分的使用多核cpu的资源,os.cpu_count可以查看逻辑cpu数,在python中大部分情况需要使用多进程,python提供了multiprocessing

muliprocessing模块用来开启子进程,并在子进程中执行我们制定的任务(比如函数),这个模块与多

线程模块threading编程接口类似

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

multiprocessing与线程不同的是进程没有任何共享状态,进程修改数据仅限于该进程内

Process类

Process(group,target=func,name=str,args(x,),kwargs={‘num‘:1,})

由该类实例化得到的对象,表示一个子进程中的任务

强调:需要使用关键字的方式来给Process传参数

  args指定的为target对应的函数传位置参数,是元组形式,括号类必须有逗号

参数介绍:

 

1 group参数未使用,值始终为None
2 
3 target表示调用对象,即子进程要执行的任务
4 
5 args表示调用对象的位置参数元组,args=(1,2,‘egon‘,)
6 
7 kwargs表示调用对象的字典,kwargs={‘name‘:‘egon‘,‘age‘:18}
8 
9 name为子进程的名称


方法介绍:

1.P.start()启动进程,并调用该子进程中的P.run()
2.P.run()进程启动时运行的方法,他去调用target指定的函数,我们在自定义/继承与Process的类总一定要实现run()这个方法
3.P.terminate()强制终止进程p,不会进行任何清理操作,如果p创建了子进程,那么这个子进程就成了僵尸进程
  使用该方法需要特别小心这种情况,如果p还保存了一个锁那么也将不会被释放,进而导致死锁
4.P.is_alive()如果p任然在运行,那么返回True
5.P.join([timeout])主线程序等待p终止(强调,是主线程序处于等待状态,p处于运行状态),timeout是可选的
  超时时间,P.join()只能join住start开启的进程,放在start()下边,而不能join住run开启的进程

属性介绍:

p.deamon,默认值为False,如果设为True,代表p为后台运行的守护进程,当p父进程终止时,p也随之终止,并且
设定为True后,p不能创建自己的新进程,p.deamon必须在p.start()之前设置

p.name进程的名称

p.pid进程的id


process类的使用

在windo中process()必须放到if__name__==‘__main__‘:下去运行,不会在导入时被调用

由于window没有fork,多处理模块启动一个新的python进程并导入调用模块
如果在导入时调用process(),name这将启动无限继承的新进程(或直到机器耗尽资源)

创建并开启子进程的两种方式

#开进程的方法一:
import time
import random
from multiprocessing import Process
def piao(name):
print(‘%s piaoing‘ %name)
time.sleep(random.randrange(1,5))
print(‘%s piao end‘ %name)

 

p1=Process(target=piao,args=(‘egon‘,)) #必须加,号
p2=Process(target=piao,args=(‘alex‘,))
p3=Process(target=piao,args=(‘wupeqi‘,))
p4=Process(target=piao,args=(‘yuanhao‘,))

p1.start()
p2.start()
p3.start()
p4.start()
print(‘主线程‘)

方法一


#开进程的方法二:
import time
import random
from multiprocessing import Process


class Piao(Process):
def __init__(self,name):
super().__init__()
self.name=name
def run(self):
print(‘%s piaoing‘ %self.name)

time.sleep(random.randrange(1,5))
print(‘%s piao end‘ %self.name)

p1=Piao(‘egon‘)
p2=Piao(‘alex‘)
p3=Piao(‘wupeiqi‘)
p4=Piao(‘yuanhao‘)

p1.start() #start会自动调用run
p2.start()
p3.start()
p4.start()
print(‘主线程‘)

方法二

 

进程直接的内存空间是隔离的

 

 

守护进程

主进程创建守护进程

  其一:守护进程会在主进程代码执行结束后就终止

  其二:守护进程内无法再开启子进程,否则抛出异常:AssertionError: daemonic processes are not allowed to have children

注意:进程之间是互相独立的,主进程代码运行结束,守护进程随即终止

from multiprocessing import Process
import time
import random

class Piao(Process):
def __init__(self,name):
self.name=name
super().__init__()
def run(self):
print(‘%s is piaoing‘ %self.name)
time.sleep(random.randrange(1,3))
print(‘%s is piao end‘ %self.name)


p=Piao(‘egon‘)
p.daemon=True #一定要在p.start()前设置,设置p为守护进程,禁止p创建子进程,并且父进程代码执行结束,p即终止运行
p.start()
print(‘主‘)

 

 

 

进程同步(锁)

进程之间数据不共享,但是共享同一套文件系统,所以访问同一个文件,或同一个打印终端,是没有问题的,

而共享带来的是竞争,竞争带来的结果就是错乱,如何控制,就是加锁处理

 

#文件db的内容为:{"count":1}
#注意一定要用双引号,不然json无法识别
from multiprocessing import Process,Lock
import time,json,random
def search():
dic=json.load(open(‘db.txt‘))
print(‘33[43m剩余票数%s33[0m‘ %dic[‘count‘])

def get():
dic=json.load(open(‘db.txt‘))
time.sleep(0.1) #模拟读数据的网络延迟
if dic[‘count‘] >0:
dic[‘count‘]-=1
time.sleep(0.2) #模拟写数据的网络延迟
json.dump(dic,open(‘db.txt‘,‘w‘))
print(‘33[43m购票成功33[0m‘)

def task(lock):
search()
lock.acquire()
get()
lock.release()
if __name__ == ‘__main__‘:
lock=Lock()
for i in range(100): #模拟并发100个客户端抢票
p=Process(target=task,args=(lock,))
p.start()

加锁:购票行为由并发变成了串行,牺牲了运行效率,但保证了数据安全

 

#加锁可以保证多个进程修改同一块数据时,同一时间只能有一个任务可以进行修改,即串行的修改,没错,速度是慢了,但牺牲了速度却保证了数据安全。
虽然可以用文件共享数据实现进程间通信,但问题是:
1.效率低(共享数据基于文件,而文件是硬盘上的数据)
2.需要自己加锁处理

 



































































































以上是关于python 多进程的主要内容,如果未能解决你的问题,请参考以下文章

[Python3] 043 多线程 简介

python中的多线程和多进程编程

代码片段:Shell脚本实现重复执行和多进程

线程学习知识点总结

什么是多线程,多进程?

多线程编程