Python自定义进程池实例分析【生产者、消费者模型问题】


Posted in Python onSeptember 19, 2016

本文实例分析了Python自定义进程池。分享给大家供大家参考,具体如下:

代码说明一切:

#encoding=utf-8
#author: walker
#date: 2014-05-21
#function: 自定义进程池遍历目录下文件
from multiprocessing import Process, Queue, Lock
import time, os
#消费者
class Consumer(Process):
  def __init__(self, queue, ioLock):
    super(Consumer, self).__init__()
    self.queue = queue
    self.ioLock = ioLock
  def run(self):
    while True:
      task = self.queue.get()  #队列中无任务时,会阻塞进程
      if isinstance(task, str) and task == 'quit':
        break;
      time.sleep(1)  #假定任务处理需要1秒钟
      self.ioLock.acquire()
      print( str(os.getpid()) + ' ' + task)
      self.ioLock.release()
    self.ioLock.acquire()
    print 'Bye-bye'
    self.ioLock.release()
#生产者
def Producer():
  queue = Queue()  #这个队列是进程/线程安全的
  ioLock = Lock()
  subNum = 4  #子进程数量
  workers = build_worker_pool(queue, ioLock, subNum)
  start_time = time.time()
  for parent, dirnames, filenames in os.walk(r'D:\test'):
    for filename in filenames:
      queue.put(filename)
      ioLock.acquire()
      print('qsize:' + str(queue.qsize()))
      ioLock.release()
      while queue.qsize() > subNum * 10: #控制队列中任务数量
        time.sleep(1)
  for worker in workers:
    queue.put('quit')
  for worker in workers:
    worker.join()
  ioLock.acquire()
  print('Done! Time taken: {}'.format(time.time() - start_time))
  ioLock.release()
#创建进程池
def build_worker_pool(queue, ioLock, size):
  workers = []
  for _ in range(size):
    worker = Consumer(queue, ioLock)
    worker.start()
    workers.append(worker)
  return workers
if __name__ == '__main__':
  Producer()

ps:

self.ioLock.acquire()
...
self.ioLock.release()

可用:

with self.ioLock:
  ...

替代。

再来一个好玩的例子:

#encoding=utf-8
#author: walker
#date: 2016-01-06
#function: 一个多进程的好玩例子
import os, sys, time
from multiprocessing import Pool
cur_dir_fullpath = os.path.dirname(os.path.abspath(__file__))
g_List = ['a']
#修改全局变量g_List
def ModifyDict_1():
  global g_List
  g_List.append('b')
#修改全局变量g_List
def ModifyDict_2():
  global g_List
  g_List.append('c')
#处理一个
def ProcOne(num):
  print('ProcOne ' + str(num) + ', g_List:' + repr(g_List))
#处理所有
def ProcAll():
  pool = Pool(processes = 4)
  for i in range(1, 20):
    #ProcOne(i)
    #pool.apply(ProcOne, (i,))
    pool.apply_async(ProcOne, (i,))
  pool.close()
  pool.join()
ModifyDict_1() #修改全局变量g_List
if __name__ == '__main__':
  ModifyDict_2() #修改全局变量g_List
  print('In main g_List :' + repr(g_List))
  ProcAll()

Windows7 下运行的结果:

λ python3 demo.py
In main g_List :['a', 'b', 'c']
ProcOne 1, g_List:['a', 'b']
ProcOne 2, g_List:['a', 'b']
ProcOne 3, g_List:['a', 'b']
ProcOne 4, g_List:['a', 'b']
ProcOne 5, g_List:['a', 'b']
ProcOne 6, g_List:['a', 'b']
ProcOne 7, g_List:['a', 'b']
ProcOne 8, g_List:['a', 'b']
ProcOne 9, g_List:['a', 'b']
ProcOne 10, g_List:['a', 'b']
ProcOne 11, g_List:['a', 'b']
ProcOne 12, g_List:['a', 'b']
ProcOne 13, g_List:['a', 'b']
ProcOne 14, g_List:['a', 'b']
ProcOne 15, g_List:['a', 'b']
ProcOne 16, g_List:['a', 'b']
ProcOne 17, g_List:['a', 'b']
ProcOne 18, g_List:['a', 'b']
ProcOne 19, g_List:['a', 'b']

Ubuntu 14.04下运行的结果:

In main g_List :['a', 'b', 'c']
ProcOne 1, g_List:['a', 'b', 'c']
ProcOne 2, g_List:['a', 'b', 'c']
ProcOne 3, g_List:['a', 'b', 'c']
ProcOne 5, g_List:['a', 'b', 'c']
ProcOne 4, g_List:['a', 'b', 'c']
ProcOne 8, g_List:['a', 'b', 'c']
ProcOne 9, g_List:['a', 'b', 'c']
ProcOne 7, g_List:['a', 'b', 'c']
ProcOne 11, g_List:['a', 'b', 'c']
ProcOne 6, g_List:['a', 'b', 'c']
ProcOne 12, g_List:['a', 'b', 'c']
ProcOne 13, g_List:['a', 'b', 'c']
ProcOne 10, g_List:['a', 'b', 'c']
ProcOne 14, g_List:['a', 'b', 'c']
ProcOne 15, g_List:['a', 'b', 'c']
ProcOne 16, g_List:['a', 'b', 'c']
ProcOne 17, g_List:['a', 'b', 'c']
ProcOne 18, g_List:['a', 'b', 'c']
ProcOne 19, g_List:['a', 'b', 'c']

可以看见Windows7下第二次修改没有成功,而Ubuntu下修改成功了。据uliweb作者limodou讲,原因是Windows下是充重启实现的子进程;Linux下是fork实现的。

希望本文所述对大家Python程序设计有所帮助。

Python 相关文章推荐
Python的GUI框架PySide的安装配置教程
Feb 16 Python
Python网络爬虫出现乱码问题的解决方法
Jan 05 Python
用Python3创建httpServer的简单方法
Jun 04 Python
python实现本地批量ping多个IP的方法示例
Aug 07 Python
python 用户交互输入input的4种用法详解
Sep 24 Python
Python OrderedDict的使用案例解析
Oct 25 Python
numpy实现神经网络反向传播算法的步骤
Dec 24 Python
Selenium 滚动页面至元素可见的方法
Mar 18 Python
idea2020手动安装python插件的实现方法
Jul 17 Python
python高级特性简介
Aug 13 Python
Python中requests做接口测试的方法
May 30 Python
Python基本知识点总结
Apr 07 Python
python安装PIL模块时Unable to find vcvarsall.bat错误的解决方法
Sep 19 #Python
Python操作Access数据库基本步骤分析
Sep 19 #Python
Python自定义主从分布式架构实例分析
Sep 19 #Python
Python实现网络端口转发和重定向的方法
Sep 19 #Python
Python中__init__.py文件的作用详解
Sep 18 #Python
Python简单遍历字典及删除元素的方法
Sep 18 #Python
Python实现压缩与解压gzip大文件的方法
Sep 18 #Python
You might like
PHP设计模式之调解者模式的深入解析
2013/06/13 PHP
微信随机生成红包金额算法php版
2016/07/21 PHP
PHP strcmp()和strcasecmp()的区别实例
2016/11/05 PHP
PHP带节点操作的无限分类实现方法详解
2016/11/09 PHP
extjs 学习笔记(三) 最基本的grid
2009/10/15 Javascript
Javascript异步编程的4种方法让你写出更出色的程序
2013/01/17 Javascript
JavaScript中的函数重载深入理解
2014/08/04 Javascript
jQuery中slideUp()方法用法分析
2014/12/24 Javascript
在JavaScript的AngularJS库中进行单元测试的方法
2015/06/23 Javascript
js动态生成Html元素实现Post操作(createElement)
2015/09/14 Javascript
js调用webservice构造SOAP进行身份验证
2016/04/27 Javascript
详细讲解JavaScript中的this绑定
2016/10/10 Javascript
javascript入门之数组[新手必看]
2016/11/21 Javascript
纯原生js实现table表格的增删
2017/01/05 Javascript
angular 基于ng-messages的表单验证实例
2017/05/04 Javascript
nodejs express配置自签名https服务器的方法
2018/05/22 NodeJs
Vue项目中ESlint规范示例代码
2019/07/04 Javascript
jquery实现加载更多"转圈圈"效果(示例代码)
2020/11/09 jQuery
python ElementTree 基本读操作示例
2009/04/09 Python
简介Python中用于处理字符串的center()方法
2015/05/18 Python
一步步解析Python斗牛游戏的概率
2016/02/12 Python
利用numpy+matplotlib绘图的基本操作教程
2017/05/03 Python
python使用magic模块进行文件类型识别方法
2018/12/08 Python
基于python if 判断选择结构的实例详解
2019/05/06 Python
美体小铺英国官网:The Body Shop英国
2017/01/24 全球购物
稀有和绝版书籍:Biblio.com
2017/02/02 全球购物
美国礼品卡交易网站:Cardpool
2018/08/27 全球购物
大学社团活动策划书
2014/01/26 职场文书
旅游市场营销方案
2014/03/09 职场文书
活动总结书
2014/05/08 职场文书
法律顾问服务方案
2014/05/15 职场文书
2016年暑假家长对孩子评语
2015/12/01 职场文书
2016年优秀团员事迹材料
2016/02/25 职场文书
MySQL pt-slave-restart工具的使用简介
2021/04/07 MySQL
详解Flutter网络请求Dio库的使用及封装
2022/04/14 Java/Android
详解Spring Security如何在权限中使用通配符
2022/06/28 Java/Android