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高并发异步服务器核心库forkcore使用方法
Nov 26 Python
python3简单实现微信爬虫
Apr 09 Python
解决python3中自定义wsgi函数,make_server函数报错的问题
Nov 21 Python
python获取文件路径、文件名、后缀名的实例
Apr 23 Python
python生成以及打开json、csv和txt文件的实例
Nov 16 Python
对python opencv 添加文字 cv2.putText 的各参数介绍
Dec 05 Python
Python3 max()函数基础用法
Feb 19 Python
Anaconda 查看、创建、管理和使用python环境的方法
Dec 03 Python
Python 列表的清空方式
Jan 13 Python
你需要学会的8个Python列表技巧
Jun 24 Python
如何解决flask修改静态资源后缓存文件不能及时更改问题
Aug 02 Python
python flask框架快速入门
May 14 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入门学习知识点二 PHP简单的分页过程与原理
2011/07/14 PHP
PHP逐行输出(ob_flush与flush的组合)
2012/02/04 PHP
PHP延迟静态绑定示例分享
2014/06/22 PHP
php 使用curl模拟登录人人(校内)网的简单实例
2016/06/06 PHP
php提取微信账单的有效信息
2018/10/01 PHP
jquery控制listbox中项的移动并排序
2009/11/12 Javascript
为原生js Array增加each方法
2012/04/07 Javascript
javascript设计模式之工厂模式示例讲解
2014/03/04 Javascript
深入分析jquery解析json数据
2014/12/09 Javascript
node.js中的fs.readdir方法使用说明
2014/12/17 Javascript
js实现精美的图片跟随鼠标效果实例
2015/05/16 Javascript
javascript返回顶部的按钮实现方法
2016/01/09 Javascript
浅析javaScript中的浅拷贝和深拷贝
2017/02/15 Javascript
jQuery编写textarea输入字数限制代码
2017/03/23 jQuery
vue.js学习笔记之v-bind和v-on解析
2018/05/03 Javascript
Vue中div contenteditable 的光标定位方法
2018/08/25 Javascript
TensorFlow入门使用 tf.train.Saver()保存模型
2018/04/24 Python
Python函数参数操作详解
2018/08/03 Python
浅谈python连续赋值可能引发的错误
2018/11/10 Python
Python学习笔记之图片人脸检测识别实例教程
2019/03/06 Python
利用OpenCV和Python实现查找图片差异
2019/12/19 Python
Flask中sqlalchemy模块的实例用法
2020/08/02 Python
Pycharm无法打开双击没反应的问题及解决方案
2020/08/17 Python
Abe’s of Maine:自1979以来销售相机和电子产品
2016/11/21 全球购物
39美元购买一副眼镜或太阳镜:39DollarGlasses.com
2018/06/17 全球购物
英国最大的自有市场,比亚马逊便宜:Flubit
2019/03/19 全球购物
亿企通软件测试面试题
2012/04/10 面试题
Java程序员面试题
2016/09/27 面试题
经典的班主任推荐信
2013/10/28 职场文书
建筑项目策划书
2014/01/13 职场文书
海南地接欢迎词
2014/01/14 职场文书
项目考察欢迎辞
2014/01/17 职场文书
宿舍标语大全
2014/06/19 职场文书
升学宴学生致辞
2015/07/27 职场文书
再读《皇帝的新衣》的读后感悟!
2019/08/07 职场文书
Java设计模式中的命令模式
2022/04/28 Java/Android