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

作者:RQSLT 时间:2023-05-20 12:20:02 

本文实例分析了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,自定义,进程池
0
投稿

猜你喜欢

  • Python使用win32com实现的模拟浏览器功能示例

    2023-09-21 14:13:13
  • python实现蒙特卡罗模拟法的实践

    2023-08-11 02:22:02
  • python线程定时器Timer实现原理解析

    2022-01-08 20:25:36
  • 使用python-opencv读取视频,计算视频总帧数及FPS的实现

    2022-02-03 06:55:34
  • 用Mysql查询语句记录

    2011-02-16 12:29:00
  • 对架构师的建议:博学笃志,切问近思

    2009-09-25 12:55:00
  • PHP _construct()函数讲解

    2023-06-14 16:56:43
  • 利用Python将社交网络进行可视化

    2022-12-18 07:07:15
  • JS清除IE浏览器缓存的方法

    2024-04-19 10:15:25
  • python实现将一个数组逆序输出的方法

    2022-07-16 11:07:51
  • SQL Server 复制需要有实际的服务器名称才能连接到服务器

    2024-01-18 09:17:15
  • MYSQL教程:查询优化之有效加载数据

    2009-02-27 15:45:00
  • python装饰器原理与用法深入详解

    2021-01-13 09:17:19
  • 如何获得ADO的连接信息?

    2009-11-23 20:33:00
  • MySQL Delete 删数据后磁盘空间未释放的原因

    2024-01-23 10:56:14
  • python之文件的读写和文件目录以及文件夹的操作实现代码

    2021-05-15 02:55:57
  • python列表的逆序遍历实现

    2021-08-02 02:01:28
  • ubuntu16.04在python3 下创建Django项目并运行的操作方法

    2021-02-01 11:03:50
  • python使用webdriver爬取微信公众号

    2022-10-06 02:13:30
  • SQL 查询性能优化 解决书签查找

    2024-01-28 08:33:53
  • asp之家 网络编程 m.aspxhome.com