赞
踩
multiprocessing模块:是一个跨平台跨版本的多进程模块,提供了一个Process类来代表一个进程对象,这个对象可以理解为是一个独立的进程,可以执行另外的事情。
Process([group[,target[,name[,args[,kwargs]]]]])
target: 如果传递了函数的引用,子进程就会执行这个函数的代码
args: 给target指定的函数传递的参数,以元组的方式传递
kwargs: 给target指定的函数传递的关键字参数
name: 给进程设定一个名字,可以不设定。
group: 指定进程组,大多数情况用不到
Process创建的实例对象常用的方法
start(): 启动子进程实例(创建子进程)
is_alive(): 判断子进程是否还活着
join([timeout]): 是否等待子进程结束,或等待多少秒
terminate(): 不管任务是否完成,立即终止子进程
Process创建的实例对象常用的属性
name: 当前进程的别名,默认为Process-N,N从1开始递增的整数
pid: 当前进程的pid(进程号)
- from multiprocessing import Process
- import time
-
- num = 0
-
-
- def func1():
- global num
- for i in range(5):
- print("-----这是进程1-----:{}".format(num))
- num += 1
- time.sleep(0.5)
-
-
- def func2():
- global num
- for i in range(5):
- print("-----这是进程2-----:{}".format(num))
- num += 1
- time.sleep(0.5)
-
-
- if __name__ == '__main__':
- p1 = Process(target=func1)
- p2 = Process(target=func2)
-
- p1.start()
- p2.start()
-
-
- 输出:
- -----这是进程1-----:0
- -----这是进程2-----:0
- -----这是进程1-----:1
- -----这是进程2-----:1
- -----这是进程1-----:2
- -----这是进程2-----:2
- -----这是进程2-----:3
- -----这是进程1-----:3
- -----这是进程1-----:4
- -----这是进程2-----:4
以上可以发现:2个进程的操作的变量num是不共享的(线程间全局变量共享)。
原因:进程在创建时,操作系统会为每个进程分配独立的内存资源,每个进程运行时的信息都保存在各自的内存空间中,互不干扰,所以全局变量时不共享的。
随之而来的问题:多进程之间如何通讯,处理同一组数据达到提效的目的?
from multiprocessing import Process,Queue
答案:队列(multiprocessing.Queue(),进程专用的Queue,不是线程级别的Queue),可以使用multiprocessing模块的Queue实现多进程之间的数据传递,Queue本身是一个消息队列程序。
进程间通信multiproccessing.Queue()和线程间通信queue.Queue() :
1.queue.Queue()是进程内的非阻塞队列。
2.multiprocessing.Queue()是跨进程通信的队列。
⭐️注意:进程之间的queue要当作参数传进去(不共享全局变量)
两个子进程消费同一个消息队列中的数据示例:
- from multiprocessing import Process, Queue
- import time
-
-
- def work1(q):
- """
- 子进程work1
- :param q:传入队列,子进程中开始消费队列中的数据
- :return:
- """
- # while True:
- # if not q.empty():
- while not q.empty():
- data = q.get()
- print("--work1正在执行任务---{}".format(data))
- time.sleep(1)
-
-
- def work2(q):
- # while True:
- # if not q.empty():
- while not q.empty():
- value = q.get()
- print("---work2正在执行任务----{}".format(value))
- time.sleep(1)
-
-
- if __name__ == '__main__':
- q = Queue()
- for i in range(1, 11):
- q.put(i)
- p1 = Process(target=work1, args=(q,))
- p2 = Process(target=work2, args=(q,))
- s_time = time.time()
- p1.start()
- p2.start()
- p1.join()
- p2.join()
- e_time = time.time()
- print("两个子进程消费同一个队列中的10条数据,共耗时:{}秒".format(e_time - s_time))
- print("all datas have been writen and been read")
'运行
输出:
从以上示例看出,每个子进程中消费一条数据都要停留1秒,如果多进程没有起到预期效果的话,总计耗时应该是10秒+,但是启用多进程后,总计耗时为5秒+。
multiprocessing 模块可利用硬件中的多CPU优势,但是threading 模块中的多线程只能使用多CPU硬件中的1个CPU。
总结:计算密集型建议使用多进程multiprocessing中的Process类+Queue类。
from multiprocessing import Process,Queue
'运行
IO密集型建议使用多线程threading中的Thread+queue模块中的Queue类。
- from threading import Thread
- from queue import Queue
'运行
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。