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 multiprocessing.Manager介绍和实例(进程间共享数据)
Nov 21 Python
python下如何查询CS反恐精英的服务器信息
Jan 17 Python
python 二分查找和快速排序实例详解
Oct 13 Python
django上传图片并生成缩略图方法示例
Dec 11 Python
Django rest framework基本介绍与代码示例
Jan 26 Python
python利用tkinter实现屏保
Jul 30 Python
pandas DataFrame行或列的删除方法的实现示例
Aug 02 Python
pytorch torch.nn.AdaptiveAvgPool2d()自适应平均池化函数详解
Jan 03 Python
django有外键关系的两张表如何相互查找
Feb 10 Python
python实点云分割k-means(sklearn)详解
May 28 Python
将pycharm配置为matlab或者spyder的用法说明
Jun 08 Python
python实现视频压缩功能
Dec 18 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
使用 laravel sms 构建短信验证码发送校验功能
2017/11/06 PHP
javascript 面向对象编程  function是方法(函数)
2009/09/17 Javascript
js制作的鼠标悬浮时产生的下拉框效果
2012/10/27 Javascript
jQuery移动和复制dom节点实用DOM操作案例
2012/12/17 Javascript
关于jQuery参考实例2.0 用jQuery选择元素
2013/04/07 Javascript
Jquery网页出现的乱码问题的三种解决方法
2013/06/30 Javascript
一个不错的字符串转码解码函数(自写)
2014/07/31 Javascript
javascript实现禁止鼠标滚轮事件
2015/07/24 Javascript
JavaScript实现简单获取当前网页网址的方法
2015/11/09 Javascript
JS中call/apply、arguments、undefined/null方法详解
2016/02/15 Javascript
Node.js的项目构建工具Grunt的安装与配置教程
2016/05/12 Javascript
jQuery插件Validation快速完成表单验证的方式
2016/07/28 Javascript
jQuery Dialog 取消右上角删除按钮事件
2016/09/07 Javascript
javascript合并两个数组最简单的实现方法
2019/09/14 Javascript
基于Vue的商品主图放大镜方案详解
2019/09/19 Javascript
vue cli3适配所有端方案的实现
2020/04/13 Javascript
Vue组件跨层级获取组件操作
2020/07/27 Javascript
vue-cli4.0多环境配置变量与模式详解
2020/12/30 Vue.js
详细介绍Python中的偏函数
2015/04/27 Python
Python中.join()和os.path.join()两个函数的用法详解
2018/06/11 Python
基于django channel实现websocket的聊天室的方法示例
2019/04/11 Python
Python实战之制作天气查询软件
2019/05/14 Python
浅析Python语言自带的数据结构有哪些
2019/08/27 Python
python利用xlsxwriter模块 操作 Excel
2020/10/14 Python
python在地图上画比例的实例详解
2020/11/13 Python
SISLEY希思黎官方旗舰店:享誉全球的奢华植物美容品牌
2018/04/25 全球购物
伦敦著名的运动鞋综合商店:Footpatrol
2019/03/25 全球购物
StubHub中国:购买和出售全球活动门票
2020/01/01 全球购物
介绍一下except的用法和作用
2015/01/22 面试题
会计出纳岗位职责
2013/12/25 职场文书
会计专业个人自我鉴定
2014/03/21 职场文书
竞聘书格式及范文
2014/03/31 职场文书
瘦西湖导游词
2015/02/03 职场文书
幼儿园老师个人总结
2015/02/28 职场文书
运动会班级口号霸气押韵
2015/12/24 职场文书
基于python实现银行管理系统
2021/04/20 Python