多进程使用multiprocessing.Process及进程专用的Queue

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

  • 3
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
以下是一个使用`multiprocessing.apply_async`函数处理多个`multiprocessing.Manager.Queue()`的示例代码: ```python import multiprocessing def worker(q1, q2): while True: item = q1.get() if item is None: break # 处理item result = item + 1 q2.put(result) if __name__ == '__main__': manager = multiprocessing.Manager() q1 = manager.Queue() q2 = manager.Queue() # 启动worker进程 p = multiprocessing.Process(target=worker, args=(q1, q2)) p.start() # 向队列q1中添加数据 for i in range(10): q1.put(i) # 添加结束标记 q1.put(None) # 从队列q2中读取结果 results = [] for i in range(10): result = q2.get() results.append(result) # 等待worker进程结束 p.join() print(results) ``` 在示例代码中,我们首先创建了两个`multiprocessing.Manager.Queue()`对象:`q1`和`q2`。然后我们启动了一个worker进程,将`q1`和`q2`作为参数传递给worker函数。在worker函数中,我们使用无限循环来不断地从`q1`队列中读取数据,并对每个数据进行处理,然后将结果放入`q2`队列中。当从`q1`中取到None时,说明数据已经全部处理完毕,此时退出循环。 在主进程中,我们向`q1`队列中添加10个数据,并在最后添加一个None作为结束标记。然后我们使用循环从`q2`队列中读取结果,并将结果保存到一个列表中。最后我们等待worker进程结束,并输出结果列表。 需要注意的是,`multiprocessing.Manager.Queue()`对象进程安全的队列,可以在多个进程之间共享数据。在上面的示例代码中,我们通过`multiprocessing.Process`函数启动了一个worker进程,并将`q1`和`q2`队列作为参数传递给worker函数。在worker函数中,我们可以直使用`q1`和`q2`队列来进行数据的读取和写入。这样就可以实现多个进程之间的通信和协作。

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

chuntian_tester

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值