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中的startswith和endswith函数使用实例
Aug 25 Python
Python中使用PyQt把网页转换成PDF操作代码实例
Apr 23 Python
Python基本语法经典教程
Mar 11 Python
Django中login_required装饰器的深入介绍
Nov 24 Python
Windows下安装Django框架的方法简明教程
Mar 28 Python
详解python使用turtle库来画一朵花
Mar 21 Python
Python socket实现的文件下载器功能示例
Nov 15 Python
Django将默认的SQLite更换为MySQL的实现
Nov 18 Python
Python中SQLite如何使用
May 27 Python
Pandas读取csv时如何设置列名
Jun 02 Python
几款好用的python工具库(小结)
Oct 20 Python
Python的轻量级ORM框架peewee使用教程
Feb 05 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
DOTA2游戏同人动画《龙之血》导演接受采访
2021/03/05 欧美动漫
ip签名探针
2006/10/09 PHP
Win2003服务器安全加固设置--进一步提高服务器安全性
2007/05/23 PHP
PHP下常用正则表达式整理
2010/10/26 PHP
PHP获取当前url的具体方法全面解析
2013/11/26 PHP
Thinkphp搭建包括JS多语言的多语言项目实现方法
2014/11/24 PHP
PHP中使用Imagick实现各种图片效果实例
2015/01/21 PHP
使用纯php代码实现页面伪静态的方法
2015/07/25 PHP
php批量删除超链接的实现方法
2015/10/19 PHP
PHP Smarty模版简单使用方法
2016/03/30 PHP
PHP微信API接口类
2016/08/22 PHP
PHP中“=>
2019/03/01 PHP
yii 框架实现按天,月,年,自定义时间段统计数据的方法分析
2020/04/04 PHP
简单几行JS Code实现IE邮件转发新浪微博
2013/07/03 Javascript
javascript 实现 原路返回
2015/01/21 Javascript
JavaScript 链式结构序列化详解
2016/09/30 Javascript
js时间戳和c#时间戳互转方法(推荐)
2017/02/15 Javascript
JS基于对象的特性实现去除数组中重复项功能详解
2017/11/17 Javascript
12个提高JavaScript技能的概念(小结)
2019/05/09 Javascript
layui-tree实现Ajax异步请求后动态添加节点的方法
2019/09/23 Javascript
python生成随机验证码(中文验证码)示例
2014/04/03 Python
深入解析Python中的线程同步方法
2016/06/14 Python
python利用requests库模拟post请求时json的使用教程
2018/12/07 Python
python-tkinter之按钮的使用,开关方法
2019/06/11 Python
python opencv minAreaRect 生成最小外接矩形的方法
2019/07/01 Python
Django中的AutoField字段使用
2020/05/18 Python
面向新手解析python Beautiful Soup基本用法
2020/07/11 Python
python 实现弹球游戏的示例代码
2020/11/17 Python
皇家道尔顿官网:Royal Doulton
2017/12/06 全球购物
澳大利亚100%丝绸多彩度假装商店:TheSwankStore
2019/09/04 全球购物
30年同学聚会感言
2014/01/30 职场文书
农业项目建议书
2014/08/25 职场文书
公安领导班子四风问题个人整改措施思想汇报
2014/10/09 职场文书
创业计划书之奶茶店开店方案范本!
2019/08/06 职场文书
浅谈mysql哪些情况会导致索引失效
2021/11/20 MySQL
Mysql开启外网访问
2022/05/15 MySQL