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实现的一只从百度开始不断搜索的小爬虫
Aug 13 Python
在Python中使用模块的教程
Apr 27 Python
Python实现信用卡系统(支持购物、转账、存取钱)
Jun 24 Python
Python制作简易注册登录系统
Dec 15 Python
利用python打印出菱形、三角形以及矩形的方法实例
Aug 08 Python
50行Python代码实现人脸检测功能
Jan 23 Python
详解Python中where()函数的用法
Mar 27 Python
python消费kafka数据批量插入到es的方法
Dec 27 Python
python flask安装和命令详解
Apr 02 Python
Pytorch mask_select 函数的用法详解
Feb 18 Python
python 中的9个实用技巧,助你提高开发效率
Aug 30 Python
Python web框架(django,flask)实现mysql数据库读写分离的示例
Nov 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
无线电广播与收音机发展的历史回眸
2021/03/02 无线电
用PHP实现多级树型菜单
2006/10/09 PHP
php与paypal整合方法
2010/11/28 PHP
[Web]防止用户复制页面内容和另存页面的方法
2009/02/06 Javascript
JavaScript 拾漏补遗
2009/12/27 Javascript
jquery修改网页背景颜色通过css方法实现
2014/06/06 Javascript
jquery插件推荐 jquery.cookie
2014/11/09 Javascript
JavaScript中实现依赖注入的思路分享
2015/01/15 Javascript
javascript判断css3动画结束 css3动画结束的回调函数
2015/03/10 Javascript
jQuery基于json与cookie实现购物车的方法
2016/04/15 Javascript
vue组件与复用详解
2018/04/08 Javascript
js实现简单掷骰子小游戏
2019/10/24 Javascript
利用 Chrome Dev Tools 进行页面性能分析的步骤说明(前端性能优化)
2021/02/24 Javascript
[01:09:50]VP vs Pain 2018国际邀请赛小组赛BO2 第二场
2018/08/20 DOTA
[01:38]女王驾到——至宝魔廷新尊技能&特效展示
2020/06/16 DOTA
Python3.x和Python2.x的区别介绍
2013/02/12 Python
举例讲解Python的Tornado框架实现数据可视化的教程
2015/05/02 Python
python实现文本去重且不打乱原本顺序
2016/01/26 Python
Python的Django应用程序解决AJAX跨域访问问题的方法
2016/05/31 Python
详解Python中的文件操作
2016/08/28 Python
win7上python2.7连接mysql数据库的方法
2017/01/14 Python
matplotlib给子图添加图例的方法
2018/08/03 Python
python time.sleep()是睡眠线程还是进程
2019/07/09 Python
python聚类算法解决方案(rest接口/mpp数据库/json数据/下载图片及数据)
2019/08/28 Python
Python常用模块os.path之文件及路径操作方法
2019/12/03 Python
Python计算信息熵实例
2020/06/18 Python
美国宠物美容和宠物用品购物网站:Cherrybrook
2018/12/07 全球购物
应届毕业生自荐信例文
2014/02/26 职场文书
工程安全员岗位职责
2014/03/09 职场文书
搞笑车尾标语
2014/06/23 职场文书
工商管理本科生求职信
2014/07/13 职场文书
杭州西湖英语导游词
2015/02/03 职场文书
公务员保密工作承诺书
2015/05/04 职场文书
2019最新版股权转让及委托持股协议书范本
2019/08/07 职场文书
《水浒传》读后感3篇(范文)
2019/09/19 职场文书
MySQL 百万级数据的4种查询优化方式
2021/06/07 MySQL