当前位置:   article > 正文

多进程使用multiprocessing.Process及进程专用的Queue_process不能接接收queue的实例对象

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(进程号)

  1. from multiprocessing import Process
  2. import time
  3. num = 0
  4. def func1():
  5. global num
  6. for i in range(5):
  7. print("-----这是进程1-----:{}".format(num))
  8. num += 1
  9. time.sleep(0.5)
  10. def func2():
  11. global num
  12. for i in range(5):
  13. print("-----这是进程2-----:{}".format(num))
  14. num += 1
  15. time.sleep(0.5)
  16. if __name__ == '__main__':
  17. p1 = Process(target=func1)
  18. p2 = Process(target=func2)
  19. p1.start()
  20. p2.start()
  21. 输出:
  22. -----这是进程1-----:0
  23. -----这是进程2-----:0
  24. -----这是进程1-----:1
  25. -----这是进程2-----:1
  26. -----这是进程1-----:2
  27. -----这是进程2-----:2
  28. -----这是进程2-----:3
  29. -----这是进程1-----:3
  30. -----这是进程1-----:4
  31. -----这是进程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要当作参数传进去(不共享全局变量)

两个子进程消费同一个消息队列中的数据示例:

  1. from multiprocessing import Process, Queue
  2. import time
  3. def work1(q):
  4. """
  5. 子进程work1
  6. :param q:传入队列,子进程中开始消费队列中的数据
  7. :return:
  8. """
  9. # while True:
  10. # if not q.empty():
  11. while not q.empty():
  12. data = q.get()
  13. print("--work1正在执行任务---{}".format(data))
  14. time.sleep(1)
  15. def work2(q):
  16. # while True:
  17. # if not q.empty():
  18. while not q.empty():
  19. value = q.get()
  20. print("---work2正在执行任务----{}".format(value))
  21. time.sleep(1)
  22. if __name__ == '__main__':
  23. q = Queue()
  24. for i in range(1, 11):
  25. q.put(i)
  26. p1 = Process(target=work1, args=(q,))
  27. p2 = Process(target=work2, args=(q,))
  28. s_time = time.time()
  29. p1.start()
  30. p2.start()
  31. p1.join()
  32. p2.join()
  33. e_time = time.time()
  34. print("两个子进程消费同一个队列中的10条数据,共耗时:{}秒".format(e_time - s_time))
  35. 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类。         

  1. from threading import Thread
  2. from queue import Queue
'
运行

声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/从前慢现在也慢/article/detail/860597
推荐阅读
  

闽ICP备14008679号