Python实现简单多线程任务队列


Posted in Python onFebruary 27, 2016

最近我在用梯度下降算法绘制神经网络的数据时,遇到了一些算法性能的问题。梯度下降算法的代码如下(伪代码):

def gradient_descent():
  # the gradient descent code
  plotly.write(X, Y)

一般来说,当网络请求 plot.ly 绘图时会阻塞等待返回,于是也会影响到其他的梯度下降函数的执行速度。

一种解决办法是每调用一次 plotly.write 函数就开启一个新的线程,但是这种方法感觉不是很好。 我不想用一个像 cerely(一种分布式任务队列)一样大而全的任务队列框架,因为框架对于我的这点需求来说太重了,并且我的绘图也并不需要 redis 来持久化数据。

那用什么办法解决呢?我在 python 中写了一个很小的任务队列,它可以在一个单独的线程中调用 plotly.write函数。下面是程序代码。

from threading import Thread
import Queue 
import time

class TaskQueue(Queue.Queue):

首先我们继承 Queue.Queue 类。从 Queue.Queue 类可以继承 get 和 put 方法,以及队列的行为。

def __init__(self, num_workers=1):
  Queue.Queue.__init__(self)
  self.num_workers = num_workers
  self.start_workers()

初始化的时候,我们可以不用考虑工作线程的数量。

def add_task(self, task, *args, **kwargs):
  args = args or ()
  kwargs = kwargs or {}
  self.put((task, args, kwargs))

我们把 task, args, kwargs 以元组的形式存储在队列中。*args 可以传递数量不等的参数,**kwargs 可以传递命名参数。

def start_workers(self):
  for i in range(self.num_workers):
    t = Thread(target=self.worker)
    t.daemon = True
    t.start()

我们为每个 worker 创建一个线程,然后在后台删除。

下面是 worker 函数的代码:

def worker(self):
  while True:
    tupl = self.get()
    item, args, kwargs = self.get()
    item(*args, **kwargs) 
    self.task_done()

worker 函数获取队列顶端的任务,并根据输入参数运行,除此之外,没有其他的功能。下面是队列的代码:

我们可以通过下面的代码测试:

def blokkah(*args, **kwargs):
  time.sleep(5)
  print “Blokkah mofo!”

q = TaskQueue(num_workers=5)

for item in range(1):
  q.add_task(blokkah)

q.join() # wait for all the tasks to finish.

print “All done!”

Blokkah 是我们要做的任务名称。队列已经缓存在内存中,并且没有执行很多任务。下面的步骤是把主队列当做单独的进程来运行,这样主程序退出以及执行数据库持久化时,队列任务不会停止运行。但是这个例子很好地展示了如何从一个很简单的小任务写成像工作队列这样复杂的程序。

def gradient_descent():
  # the gradient descent code
  queue.add_task(plotly.write, x=X, y=Y)

修改之后,我的梯度下降算法工作效率似乎更高了。如果你很感兴趣的话,可以参考下面的代码。

from threading import Thread
import Queue
import time

class TaskQueue(Queue.Queue):

def __init__(self, num_workers=1):
Queue.Queue.__init__(self)
self.num_workers = num_workers
self.start_workers()

def add_task(self, task, *args, **kwargs):
args = args or ()
kwargs = kwargs or {}
self.put((task, args, kwargs))

def start_workers(self):
for i in range(self.num_workers):
t = Thread(target=self.worker)
t.daemon = True
t.start()

def worker(self):
while True:
tupl = self.get()
item, args, kwargs = self.get()
item(*args, **kwargs)
self.task_done()

def tests():
def blokkah(*args, **kwargs):
time.sleep(5)
print "Blokkah mofo!"

q = TaskQueue(num_workers=5)

for item in range(10):
q.add_task(blokkah)

q.join() # block until all tasks are done
print "All done!"

if __name__ == "__main__":
tests()
Python 相关文章推荐
python 快速排序代码
Nov 23 Python
Python操作SQLite数据库的方法详解【导入,创建,游标,增删改查等】
Jul 11 Python
Python编程求质数实例代码
Jan 31 Python
Python查找最长不包含重复字符的子字符串算法示例
Feb 13 Python
Django+Xadmin构建项目的方法步骤
Mar 06 Python
Python向excel中写入数据的方法
May 05 Python
利用python实现AR教程
Nov 20 Python
python argparse传入布尔参数false不生效的解决
Apr 20 Python
keras CNN卷积核可视化,热度图教程
Jun 22 Python
经验丰富程序员才知道的8种高级Python技巧
Jul 27 Python
Python中random模块常用方法的使用教程
Oct 04 Python
Python中生成随机数据安全性、多功能性、用途和速度方面进行比较
Apr 14 Python
如何在Python中编写并发程序
Feb 27 #Python
Python 多线程抓取图片效率对比
Feb 27 #Python
Python 的描述符 descriptor详解
Feb 27 #Python
简析Python的闭包和装饰器
Feb 26 #Python
Android应用开发中Action bar编写的入门教程
Feb 26 #Python
12步教你理解Python装饰器
Feb 25 #Python
Python实现字典依据value排序
Feb 24 #Python
You might like
js限制checkbox勾选的个数以及php获取多个checkbbox的方法深入解析
2013/07/18 PHP
php实现图片上传并利用ImageMagick生成缩略图
2016/03/14 PHP
PHP自定义图片缩放函数实现等比例不失真缩放的方法
2016/08/19 PHP
PHP中串行化用法示例
2016/11/16 PHP
PHP二维关联数组的遍历方式(实例讲解)
2017/10/18 PHP
用JavaScript获取DOM元素位置和尺寸大小的方法
2013/04/12 Javascript
JavaScript实现身份证验证代码
2016/02/17 Javascript
jquery对Json的各种遍历方法总结(必看篇)
2016/09/29 Javascript
angular forEach方法遍历源码解读
2017/01/25 Javascript
angular学习之ngRoute路由机制
2017/04/12 Javascript
各种选择框jQuery的选中方法(实例讲解)
2017/06/27 jQuery
ionic2屏幕适配实现适配手机、平板等设备的示例代码
2017/08/11 Javascript
微信小程序使用input组件实现密码框功能【附源码下载】
2017/12/11 Javascript
基于axios 解决跨域cookie丢失的问题
2018/09/26 Javascript
vue实现文件上传读取及下载功能
2020/11/17 Javascript
Javascript和jquery在selenium的使用过程
2019/10/31 jQuery
JS call()及apply()方法使用实例汇总
2020/07/11 Javascript
vue实现给div绑定keyup的enter事件
2020/07/31 Javascript
JavaScript实现网页tab栏效果制作
2020/11/20 Javascript
python 快速排序代码
2009/11/23 Python
Ruby元编程基础学习笔记整理
2016/07/02 Python
Python3 把一个列表按指定数目分成多个列表的方式
2019/12/25 Python
Python标准库itertools的使用方法
2020/01/17 Python
Python Flask框架实现简单加法工具过程解析
2020/06/03 Python
matplotlib bar()实现百分比堆积柱状图
2021/02/24 Python
HTML5视频支持检测(检查浏览器是否支持视频播放)
2013/06/08 HTML / CSS
H5 canvas实现贪吃蛇小游戏
2017/07/28 HTML / CSS
美国精品地毯网站:Boutique Rugs
2020/03/04 全球购物
KEEN美国官网:美国人气户外休闲鞋品牌
2021/03/09 全球购物
数据库的约束含义
2012/09/09 面试题
社团招新策划书
2014/02/04 职场文书
新任教师自我鉴定
2014/02/24 职场文书
我们的节日春节活动方案
2014/08/22 职场文书
2014年教育教学工作总结
2014/11/13 职场文书
劳动仲裁代理词范文
2015/05/25 职场文书
Python 实现Mac 屏幕截图详解
2021/10/05 Python