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的判断语句模拟三目运算
Apr 24 Python
python计算一个序列的平均值的方法
Jul 11 Python
python实现斐波那契数列的方法示例
Jan 12 Python
Python中read()、readline()和readlines()三者间的区别和用法
Jul 30 Python
Python PyCharm如何进行断点调试
Jul 05 Python
python 寻找离散序列极值点的方法
Jul 10 Python
Python3实现二叉树的最大深度
Sep 30 Python
Python常用库大全及简要说明
Jan 17 Python
将数据集制作成VOC数据集格式的实例
Feb 17 Python
Python如何安装第三方模块
May 28 Python
python中selenium库的基本使用详解
Jul 31 Python
Python面向对象之成员相关知识总结
Jun 24 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
截获网站title标签之家内容的例子
2006/10/09 PHP
PHP用户指南-cookies部分
2006/10/09 PHP
php使用NumberFormatter格式化货币的方法
2015/03/21 PHP
Laravel 5框架学习之表单验证
2015/04/08 PHP
laravel学习笔记之模型事件的几种用法示例
2017/08/15 PHP
js 图片轮播(5张图片)
2008/12/30 Javascript
jquery uaMatch源代码
2011/02/14 Javascript
Javascript类型转换的规则实例解析
2016/02/23 Javascript
jquery form表单获取内容以及绑定数据
2016/02/24 Javascript
JS中判断字符串中出现次数最多的字符及出现的次数的简单实例
2016/06/03 Javascript
JS去除空格和换行的正则表达式(推荐)
2016/06/14 Javascript
JavaScript获取当前url根目录(路径)
2016/06/17 Javascript
Bootstrap中表单控件状态(验证状态)
2016/08/04 Javascript
JS封装的三级联动菜单(使用时只需要一行js代码)
2016/10/24 Javascript
JavaScript中访问id对象 属性的方式访问属性(实例代码)
2016/10/28 Javascript
React.js中常用的ES6写法总结(推荐)
2017/05/09 Javascript
JS实现匀加速与匀减速运动的方法示例
2017/09/04 Javascript
基于Node.js模板引擎教程-jade速学与实战1
2017/09/17 Javascript
vue h5移动端禁止缩放代码
2019/10/28 Javascript
解决Vue router-link绑定事件不生效的问题
2020/07/22 Javascript
python中pygame模块用法实例
2014/10/09 Python
python去除空格和换行符的实现方法(推荐)
2017/01/04 Python
Pycharm学习教程(2) 代码风格
2017/05/02 Python
Python cookbook(数据结构与算法)通过公共键对字典列表排序算法示例
2018/03/15 Python
python dataframe向下向上填充,fillna和ffill的方法
2018/11/28 Python
Python常用库大全及简要说明
2020/01/17 Python
Python爬虫回测股票的实例讲解
2021/01/22 Python
CSS3实现的闪烁跳跃进度条示例(附源码)
2013/08/19 HTML / CSS
Omio波兰:全欧洲低价大巴、火车和航班搜索和比价
2018/02/16 全球购物
说出你对remoting 和webservice的理解和应用
2014/06/08 面试题
医生爱岗敬业演讲稿
2014/08/26 职场文书
2014领导干部四风问题查摆思想汇报
2014/09/13 职场文书
管理人员岗位职责
2015/02/14 职场文书
2015年国庆节标语大全
2015/07/30 职场文书
老兵退伍感言
2015/08/03 职场文书
关于艺术节的开幕致辞
2016/03/04 职场文书