python多进程multiprocessing包中queue、pipe、manager模块的功能介绍(超易懂哦!)

在这里插入图片描述

python多进程主要用于解决python自身含有的GIL(即全局解释器锁)所导致的不能并行任务的问题,之前已经介绍了multiprocessing包的基本使用方式,本文简要介绍一下multiprocessing包中含有的几个模块pipe(管道)、queue(队列)、manager,这几个模块在某些较为复杂的实际应用中还是很有用处的。


queue(队列)

python自身本来就带有queue模块,此模块正如其名,发挥的是队列功能,当然这种队列的传递也是能够发挥通信作用的。python官方文档的解释是queue模块实现多生产者,多消费者队列,能够在多个生产者和消费者之间通信。当信息必须安全的在多线程之间交换时,它在线程编程中是特别有用的。此模块中的 Queue 类实现了所有锁定需求的语义。

简单说queue其实就像进程或线程锁一样,起到对信息的保护作用。由于队列的存在,python函数中的生产者函数及消费者函数能够准确、有确定方向的进行通信。使这些需要被传递的信息不会因为多线程或多进程的存在而出错。queue储存某些生产者函数产生的信息,再将这些信息一起传递给消费者函数。当然这些函数可以是在不同的进程中运行的,从而达到进程间通信的效果。使用了队列后就不会有信息提前或者滞后到达消费者进程处,这样也就不容易导致信息出错或者紊乱。

multiprocessing中queue模块包含的方法有qsize()(返回队列包含元素的多少)、empty()(即给出队列是否为空的判断,空为True)、full()(即给出队列是否已满的判断,因为开始的时候设置队列可以设置最大拥有元素的多少)、put()(即将元素放入队列)、get()(从队列中获取元素,注意每获取一个队列中元素就减少一个)、close()(表示当前队列不再放入新的元素)。

例:

import multiprocessing

def test(q):
	for i in range(10):
		q.put(i)   # 将元素放入queue
	q.close()
	
def get_q(q):
	while not q.empty():    # 判断队列是否为非空,非空才继续执行下一步
		res = q.get()       # 获取一个元素
		print(res)
		# print(q.qsize())
		
if __name__ == '__main__':
	q = multiprocessing.Queue()      # 定义queue,这里可以传入参数,即队列所含最大元素量
	p1 = multiprocessing.Process(target=test,args=(q,))   # 多进程
	p2 = multiprocessing.Process(target=get_q,args=(q,))
	# 此例仅为介绍用,实际应用时创建的进程可以有丰富的功能,只需要将queue作为一个参数传入进程即可。
	p1.start()
	p2.start()
	p1.join()
	p2.join()	

结果:

在这里插入图片描述

pipe(管道)

pipe(管道)在编程语言中也是用于通信功能,即将某函数产生的结果通过管道的一端传递给管道的另一端,这就是管道名称的来源。python中管道一般用于多进程操作,可以用于在进程间传递消息。

与队列不同的地方是pipe能进行双向通信,但是队列只能单向传递消息。

例:

import multiprocessing

def test1(conn):
	conn.send('test1传送到:jack')      # 传递一个信息‘jack’
	conn.send('test1传送到:mary')	   # 传递另个信息‘mary’	
	print(conn.recv())     # 获取从管道的另一端发送来的第一个值
	print(conn.recv())     # 获取从管道的另一端发送来的第二个值
	
def test2(conn):
	conn.send('test2传送:你好')      # 传递一个信息‘你好’
	conn.send('test2传送:HELLO')    # 传递另个信息‘HELLOprint(conn.recv())    # 获取从管道的另一端发送来的第一个值
	print(conn.recv())    # 获取从管道的另一端发送来的第二个值

if __name__ == '__main__':
	p_conn,c_conn = multiprocessing.Pipe()  # 定义一个管道的两端,之后将这两端传出去
	p1 = multiprocessing.Process(target=test1,args=(p_conn,))    # 把一端给test1
	p2 = multiprocessing.Process(target=test2,args=(c_conn,))    # 另一端给test2
	p1.start()
	p2.start()
	p1.join()
	p2.join()
	# 这样就将test1与test2函数进行了管道传输,test1的内容传给了test2,test2的内容传给了test1。
	# test1与test2被分配到了不同的进程,因此这样相当于就进行了多进程中进程间的通信。

结果:

在这里插入图片描述

manager(共享内存管理)

manager模块用于多进程中共享内存的管理,其实也就是全局变量的管理。默认情况下子进程产生的全局变量仅子进程自身可以使用,主进程是获取不到子进程中全局变量的变化的。这也是因为当下使用的多核电脑的每个核都是分开工作的,即每个子进程都在不同核上工作,因此要设置全局变量就不是默认的,需要额外设置(注意:这一点不同于多线程,多线程中子线程的全局变量主线程能识别到,因为是单核运行)。

除了manager外,multiprocessing包还含有value、array也可以用于共享内存的处理。

使用value、array的例子:

import multiprocessing

def test(v,a):
	v.value = 123         			# 这里修改传入的value的值
	for i in range(len(a)):			# 这里逐个修改传入的array中的值
		a[i] = 'o'

if __name__ == '__main__':
	v = multiprocessing.Value('d')    # 将v指定为Value
	a = multiprocessing.Array('u','nihao')   # 将a指定为字符型array,官方文档提示说后续u可能被删除
	process = multiprocessing.Process(target=test,args=(v,a)) # 传入test函数,开启子进程
	process.start()
	process.join()
	print(v.value)     				  # 打印出v的值,检查是否被改变 
	print(a[:])                       # 打印出a的序列,检查是否改变

结果:

在这里插入图片描述
python官方文档说明manager支持类型有: list 、 dict 、 Namespace 、 Lock 、 RLock 、 Semaphore 、 BoundedSemaphore 、 Condition 、 Event 、 Barrier 、 Queue 、 Value 和 Array 。

此处以list和dict为例:

import multiprocessing
def test(list1,dict1):
	dict1['name1'] = 'jack'     # 增加dict1的内容
	dict1['name2'] = 'mary'     
	list1.reverse()             # 将list1中的内容颠倒
if __name__ == '__main__':
	with multiprocessing.Manager() as manager:     # 引入manager
		list1 = manager.list(range(5))             # 设置list1和dict1为共享对象
		dict1 = manager.dict()
		p = multiprocessing.Process(target=test,args=(list1,dict1))  # 传入函数中对list1与dict1修改
		p.start()
		p.join()
		print(list1)  # 检查是否修改
		print(dict1)

结果:

在这里插入图片描述

叮!

其实除了上面介绍的这些模块外还有Lock()模块也是很重要的一个模块,但是使用起来是较为简单的,这里就不再介绍了。另外还看到了semaphore模块,此模块称为信号量,用于控制线程数,即只有线程获取了信号后才能运行否则就阻塞。semaphore模块是为了防止线程数太多导致任务出错或机器故障而设计的。

参考:https://docs.python.org/zh-cn/3.6/library/multiprocessing.html#multiprocessing.Queue.empty
参考:https://blog.csdn.net/haeasringnar/article/details/79917057

  • 5
    点赞
  • 8
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
### 回答1: Python多进程multiprocessing)是一种并行计算的方式,可以在多个CPU核心上同时执行任务,提高程序的运行效率。它可以通过创建多个进程来实现并行计算,每个进程都有自己的独立内存空间,可以独立运行。在Python中,可以使用multiprocessing模块来实现多进程编程,它提供了一系列的类和函数,可以方便地创建和管理多个进程。使用multiprocessing模块可以有效地提高程序的运行速度,特别是在处理大量数据或计算密集型任务时,效果更加明显。 ### 回答2: Python多进程multiprocessing是一个用来创建并行程序的模块,它允许Python程序同时运行多个进程,从而大幅提高程序的运行效率。在Python中,多进程可以通过fork()系统调用实现,但是由于在Windows上无法完全实现fork(),因此Python在Windows上仅支持多线程,而不支持多进程Python多进程中最基本的概念是进程(Process)。在Python中,创建进程有两种基本的方式:使用Process类和使用Pool类。Process类允许我们创建一个进程对象,可以给进程传递参数并启动进程。Pool类则可以创建多个进程,并且自动分配任务到不同的进程中。 Python中还有一些重要的概念和技巧,例如进程间通信(IPC)、共享内存、信号量、锁等。进程间通信是在多进程应用程序中非常常见的技术,它可以让不同的进程之间进行数据交换、资源共享等操作。共享内存则允许不同的进程访问同一个内存区域,从而避免了复制数据的过程,提高了程序的效率。 对于使用Python多进程multiprocessing进行开发的程序,我们需要借助Python标准库中的一些附加模块,例如queue、threading、signal等,以及一些第三方库,例如PyQt、numpy等。对于不同的应用场景,我们可以选择不同的库和技术,从而实现最佳的多进程方案。 总体而言,Python多进程multiprocessing是一个非常强大的模块,可以大幅提高Python程序的运行效率和并发性能。不过,要想熟练地运用这个模块,需要对Python的多线程、操作系统和计算机架构等知识有一定的了解。同时,对于更高级别的多进程应用,可能还需要一些专业的领域知识。 ### 回答3: Python是一种面向对象、解释型、高级编程语言,其简洁、易读、易学的语法特点赢得了大批开发者的青睐。而multiprocessing则是Python的一个重要模块,可用于实现多进程并发编程,充分利用计算机多核心资源,提高Python程序的运行效率。 multiprocessing模块的主要特点包括: 1. 提供了Process、Pool、Queue等多个类和函数,方便实现进程的创建、管理和通信。 2. 可以使用fork进程创建新的进程,并可在进程之间共享数据,也可以将任务分配给多个进程执行,提高效率。 3. 提供了多种进程间通信机制的实现,如PipeQueue、Value和Array等,让进程之间的通信更加方便,同时保证数据的正确和安全。 4. 灵活的参数设置和控制,比如可以设置进程数、时时间等,让程序更加可控和稳定。 使用multiprocessing模块可以带来显著的性能提升,特别适合需要处理大规模数据、密集计算或者需要高并发的应用场景。例如,在爬取大规模网站数据时,可以把每个网站的数据抓取任务分配给不同的进程去执行,节约大量时间。在图像处理和机器学习方面也可以大大加快程序的速度。 总之,Pythonmultiprocessing模块为我们提供了一种易用、高效的多进程编程方法,使我们能够更好地利用计算机资源,提高Python程序的性能和效率。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值