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跨文件全局变量的实现方法示例
Dec 10 Python
numpy中索引和切片详解
Dec 15 Python
Python实现PS滤镜的万花筒效果示例
Jan 23 Python
详解TensorFlow在windows上安装与简单示例
Mar 05 Python
mac下pycharm设置python版本的图文教程
Jun 13 Python
详解Python列表赋值复制深拷贝及5种浅拷贝
May 15 Python
python多线程http压力测试脚本
Jun 25 Python
Python 自动登录淘宝并保存登录信息的方法
Sep 04 Python
postman传递当前时间戳实例详解
Sep 14 Python
python与pycharm有何区别
Jul 01 Python
pandas中DataFrame检测重复值的实现
May 26 Python
Python实现位图分割的效果
Nov 20 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
LAMP环境使用Composer安装Laravel的方法
2017/03/25 PHP
跨浏览器开发经验总结(四) 怎么写入剪贴板
2010/05/13 Javascript
浅析JavaScript中两种类型的全局对象/函数
2013/12/05 Javascript
JQuery $.each遍历JavaScript数组对象实例
2014/09/01 Javascript
JS学习之表格的排序简单实例
2016/05/16 Javascript
js创建对象几种方式的优缺点对比
2016/09/28 Javascript
socket.io实现在线群聊功能
2017/04/07 Javascript
jQuery返回定位插件详解
2017/05/15 jQuery
vue2.0项目集成Cesium的实现方法
2019/07/30 Javascript
js实现弹幕飞机效果
2020/08/27 Javascript
vue的webcamjs集成方式
2020/11/16 Javascript
vue+element table表格实现动态列筛选的示例代码
2021/01/14 Vue.js
python文件的md5加密方法
2016/04/06 Python
python编程测试电脑开启最大线程数实例代码
2018/02/09 Python
将pip源更换到国内镜像的详细步骤
2019/04/07 Python
Python的bit_length函数来二进制的位数方法
2019/08/27 Python
Pycharm中出现ImportError:DLL load failed:找不到指定模块的解决方法
2019/09/17 Python
SELENIUM自动化模拟键盘快捷键操作实现解析
2019/10/28 Python
python实现按首字母分类查找功能
2019/10/31 Python
CSS3 filter(滤镜)实现网页灰色或者黑色模式的示例代码
2021/02/24 HTML / CSS
为什么要优先使用同步代码块而不是同步方法?
2013/01/30 面试题
品恩科技软件测试面试题
2014/10/26 面试题
毕业生应聘幼儿园的自荐信
2013/11/20 职场文书
英文简历自荐信范文
2013/12/11 职场文书
小学公民道德宣传日活动总结
2015/03/23 职场文书
2015国际残疾人日活动总结
2015/03/24 职场文书
研究生导师推荐信
2015/03/25 职场文书
2015年妇产科工作总结
2015/05/18 职场文书
公司出差管理制度范本
2015/08/05 职场文书
2016年教师节贺卡寄语
2015/12/04 职场文书
2016年教师党员创先争优承诺书
2016/03/24 职场文书
小学四年级作文之写景
2019/08/23 职场文书
上手简单,功能强大的Python爬虫框架——feapder
2021/04/27 Python
pytorch 中autograd.grad()函数的用法说明
2021/05/12 Python
Pandas数据类型之category的用法
2021/06/28 Python
【js设计模式】SOLID五大设计原则
2022/03/24 Javascript