以下是python多进程示例
from multiprocessing import Process,current_process,RLock
num=1
lock=RLock()
def addnum(i):
global num
with lock:
num += 1
print(f"{current_process().name}:num={num}")
process_list=[]
if __name__=="__main__":
for i in range(6):
p=Process(target=addnum,args=(i,))
process_list.append(p)
p.start()
for p in process_list:
p.join()
使用进程时一定要用if name==“main”:否则会出错
这个代码首先定义了一个锁lock,然后在锁的作用下定义了函数addnum,python多进程中,最后在循环中创建了6个进程去执行函数,最后输出是所有的num都为2。
原因:因为创建进程时,所有的进程都会拷贝父进程的所有资源,所以每一个进程都会有自己的num,执行函数时,它们分别为自己的num加1,所以最后输出都为2.
如果需要共享资源,下面有3个方法,分别是Value、Manager、Queue。
内存共享(Value)
要想实现共享内存,可以使用Value,以下是示例
在示例代码中,'i'代表整型,1是初始化给共享内存变量num的值。这个语句创建的num变量是一个Value对象,可以被多个进程共享和访问。在不同的进程中,可以将num.value的值进行修改和读取。其中,.value是访问共享内存变量的方式。
from multiprocessing import Process, Value,current_process
num = Value('i', 1)
def addnum(v):
v.value += 1
print("%s: num=%s" % (current_process().name, v.value))
process_list = []
if __name__ == "__main__":
for i in range(6):
p = Process(target=addnum, args=(num,))
process_list.append(p)
p.start()
for p in process_list:
p.join()
内存共享(Manager,在windows底层使用namedpipe,在linux底层使用socket)
from multiprocessing import Process,current_process,Manager
import time
def func(i,temp):
temp[0]+=100
print(i,"-->",temp[0])
if __name__=="__main__":
manager=Manager()
temp=manager.list([1,2,3])
p_list=[]
for i in range(10):
p=Process(target=func,args=(i,temp))
p.start()
p_list.append(p)
for i in p_list:
i.join() #如果不加join,那么manager进程会先退出,子进程访问不到manager共享的数据
Manager不仅支持list、dict,还有很多类型,可以自行搜索查看。
内存共享(Queue)
from multiprocessing import Process,Queue
import time
def func(i,q):
if not q.empty():
print(i,"--->get value",q.get())
time.sleep(2)
if __name__=="__main__":
q=Queue()
for i in range(6):
q.put(10-i)
p=Process(target=func,args=(i,q))
p.start()
'''
put 插入
get 获取
full 判断是否满
empty 判断是否空
qsize 获取队列中的消息数量
'''
进程池
from multiprocessing import Pool,current_process
import time
lst=[]
def task(i):
print(current_process().name,i,'start---')
time.sleep(2)
lst.append(i)
print(f"{current_process().name}号进程",lst)
print(current_process().name,i,'end---')
if __name__=='__main__':
#建议和CPU核数一致
p=Pool(processes=4,maxtasksperchild=3)
for i in range(20):
#进程池接受任务
p.apply_async(func=task,args=(i,))
#关闭进程池,不接收任务
p.close()
#等待子进程执行完毕,父进程再执行
p.join()
print("end...")
#maxtasksperchild:每个工作进程处理3次任务就kill。这是为了把处理完任务的进程占用的内存是释放
使用进程池与没使用进程池比较
使用了进程池
没有使用进程池
可以看出使用进程池后创建2000个进程时间远比没有使用进程池的时间少。
当任务比较多时使用进程池效果更好。
以上就是python多进程的简单使用。