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之折腾一下目录
Oct 24 Python
使用Python抓取模板之家的CSS模板
Mar 16 Python
Python处理JSON时的值报错及编码报错的两则解决实录
Jun 26 Python
Python实现读取及写入csv文件的方法示例
Jan 12 Python
几种实用的pythonic语法实例代码
Feb 24 Python
详谈python3 numpy-loadtxt的编码问题
Apr 29 Python
python字符串string的内置方法实例详解
May 14 Python
Python 查看list中是否含有某元素的方法
Jun 27 Python
Python数学形态学实例分析
Sep 06 Python
django-crontab实现服务端的定时任务的示例代码
Feb 17 Python
python等差数列求和公式前 100 项的和实例
Feb 25 Python
Python包资源下载路径报404解决方案
Nov 05 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
PHP中对用户身份认证实现两种方法
2011/06/04 PHP
php设计模式 Decorator(装饰模式)
2011/06/26 PHP
PHP flush()与ob_flush()的区别详解
2013/06/03 PHP
php正则preg_replace_callback函数用法实例
2015/06/01 PHP
php数组函数array_walk用法示例
2016/05/26 PHP
PHP单元测试配置与使用方法详解
2019/12/27 PHP
PHP vsprintf()函数格式化字符串操作原理解析
2020/07/14 PHP
学习并汇集javascript匿名函数
2010/11/25 Javascript
js页面跳转常用的几种方式
2010/11/25 Javascript
$.get获取一个文件的内容示例代码
2013/09/11 Javascript
JS通过分析userAgent属性来判断浏览器的类型及版本
2014/03/28 Javascript
javascript实现youku的视频代码自适应宽度
2015/05/25 Javascript
js实现网页图片延时加载 提升网页打开速度
2016/01/26 Javascript
react-router 路由切换动画的实现示例
2018/12/03 Javascript
动态内存分配导致影响Javascript性能的问题
2018/12/18 Javascript
javascript sort()对数组中的元素进行排序详解
2019/10/13 Javascript
基于JS实现父组件的请求服务过程解析
2019/10/14 Javascript
解决VUEX的mapState/...mapState等取值问题
2020/07/24 Javascript
[02:39]DOTA2英雄基础教程 极限穿梭编织者
2013/12/05 DOTA
Python中使用异常处理来判断运行的操作系统平台方法
2015/01/22 Python
使用Python实现一个简单的项目监控
2015/03/31 Python
python清除字符串里非数字字符的方法
2015/07/02 Python
socket + select 完成伪并发操作的实例
2017/08/15 Python
浅谈Python中的私有变量
2018/02/28 Python
Python 闭包,函数分隔作用域,nonlocal声明非局部变量操作示例
2019/10/14 Python
Python 简单计算要求形状面积的实例
2020/01/18 Python
沃尔玛旗下墨西哥超市:Bodega Aurrera
2020/11/13 全球购物
我心目中的好老师活动方案
2014/08/19 职场文书
机关中层领导干部群众路线教育实践活动个人对照检查材料
2014/09/24 职场文书
初中生旷课检讨书范文
2014/10/06 职场文书
2014年内部审计工作总结
2014/12/09 职场文书
迁徙的鸟观后感
2015/06/09 职场文书
交通事故责任认定书
2015/08/06 职场文书
小学四年级班主任工作经验交流材料
2015/11/02 职场文书
《社戏》教学反思
2016/02/22 职场文书
合同补充协议书
2016/03/24 职场文书