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的Scrapy框架编写web爬虫的简单示例
Apr 17 Python
Windows上配置Emacs来开发Python及用Python扩展Emacs
Nov 20 Python
Python获取linux主机ip的简单实现方法
Apr 18 Python
pandas的object对象转时间对象的方法
Apr 11 Python
Pyqt实现无边框窗口拖动以及窗口大小改变
Apr 19 Python
python 常见字符串与函数的用法详解
Nov 23 Python
Python 从列表中取值和取索引的方法
Dec 25 Python
Python实现判断一个整数是否为回文数算法示例
Mar 02 Python
Python+PyQT5的子线程更新UI界面的实例
Jun 14 Python
python字符串分割及字符串的一些常规方法
Jul 24 Python
python中什么是面向对象
Jun 11 Python
Python-for循环的内部机制
Jun 12 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编程之设置apache虚拟目录
2016/07/08 PHP
FireFox与IE 下js兼容触发click事件的代码
2008/11/20 Javascript
通过event对象的fromElement属性解决热区设置主实体的一个bug
2008/12/22 Javascript
getComputedStyle与currentStyle获取样式(style/class)
2013/03/19 Javascript
浅析JS刷新框架中的其他页面 && JS刷新窗口方法汇总
2013/07/08 Javascript
div模拟滚动条效果示例代码
2013/10/16 Javascript
超简单JS二级、多级联动的简单实例
2014/02/18 Javascript
js中回调函数的学习笔记
2014/07/31 Javascript
AngularJS 简单应用实例
2016/07/28 Javascript
轻松实现jquery选项卡切换效果
2016/10/10 Javascript
用js控件div的滚动条,让它在内容更新时自动滚到底部的实现方法
2016/10/27 Javascript
jQuery中DOM节点删除之empty与remove
2017/01/20 Javascript
基于 Vue 的树形选择组件的示例代码
2017/08/18 Javascript
利用ES6实现单例模式及其应用详解
2017/12/09 Javascript
让axios发送表单请求形式的键值对post数据的实例
2018/08/11 Javascript
如何让node运行es6模块文件及其原理详解
2018/12/11 Javascript
JavaScript设计模式之责任链模式实例分析
2019/01/16 Javascript
vue的注意规范之v-if 与 v-for 一起使用教程
2019/08/04 Javascript
js实现无缝轮播图特效
2020/05/09 Javascript
Python实现的RSS阅读器实例
2015/07/25 Python
python进程池实现的多进程文件夹copy器完整示例
2019/11/27 Python
Python 内置变量和函数的查看及说明介绍
2019/12/25 Python
Django+boostrap 美化admin后台的操作
2020/03/11 Python
Django模板之基本的 for 循环 和 List内容的显示方式
2020/03/31 Python
pycharm无法安装第三方库的问题及解决方法以scrapy为例(图解)
2020/05/09 Python
python将字典内容写入json文件的实例代码
2020/08/12 Python
使用CSS3的appearance属性改变任何元素的浏览器默认风格
2012/12/24 HTML / CSS
HTML5拖拽文件上传的示例代码
2021/03/04 HTML / CSS
选购世界上最好的美妆品:Cult Beauty
2017/11/03 全球购物
双立人加拿大官网:Zwilling加拿大
2020/08/10 全球购物
会计应届生的自荐信
2013/12/13 职场文书
护士毕业自我鉴定
2014/02/07 职场文书
应届大专生自荐书
2014/06/16 职场文书
给老婆的检讨书1000字
2015/01/01 职场文书
庆祝教师节活动总结
2015/03/23 职场文书
一个成功的互联网创业项目,必须满足这些要求
2019/08/23 职场文书