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 相关文章推荐
在Windows8上的搭建Python和Django环境
Jul 03 Python
Python自动生产表情包
Mar 17 Python
Django如何自定义分页
Sep 25 Python
python生成lmdb格式的文件实例
Nov 08 Python
python实现逐个读取txt字符并修改
Dec 24 Python
pyqt5利用pyqtDesigner实现登录界面
Mar 28 Python
python3 tkinter实现点击一个按钮跳出另一个窗口的方法
Jun 13 Python
解决Numpy中sum函数求和结果维度的问题
Dec 06 Python
pytorch绘制并显示loss曲线和acc曲线,LeNet5识别图像准确率
Jan 02 Python
PyCharm汉化安装及永久激活详细教程(靠谱)
Jan 16 Python
tensorflow如何继续训练之前保存的模型实例
Jan 21 Python
python ImageDraw类实现几何图形的绘制与文字的绘制
Feb 26 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/11/10 PHP
php文件夹与文件目录操作函数介绍
2013/09/09 PHP
php操作MongoDB基础教程(连接、新增、修改、删除、查询)
2014/03/25 PHP
Yii框架多语言站点配置方法分析【中文/英文切换站点】
2020/04/07 PHP
简短几句jquery代码的实现一个图片向上滚动切换
2011/09/02 Javascript
探索Emberjs制作一个简单的Todo应用
2012/11/07 Javascript
jQuery 追加元素的方法如append、prepend、before
2014/01/16 Javascript
关闭页面window.location事件未执行的原因及解决方法
2014/09/01 Javascript
Jquery使用css方法改变样式实例
2015/05/18 Javascript
javascript html5实现表单验证
2016/03/01 Javascript
深入理解$.each和$(selector).each
2016/05/15 Javascript
深入理解JavaScript单体内置对象
2016/06/06 Javascript
微信小程序 时间格式化(util.formatTime(new Date))详解
2016/11/16 Javascript
jQuery EasyUI ProgressBar进度条组件
2017/02/28 Javascript
Angular项目中$scope.$apply()方法的使用详解
2017/07/26 Javascript
[js高手之路]从原型链开始图解继承到组合继承的产生详解
2017/08/28 Javascript
解决elementUI 切换tab后 el_table 固定列下方多了一条线问题
2020/07/19 Javascript
JavaScript十大取整方法实例教程
2020/12/03 Javascript
Python正则表达式实现截取成对括号的方法
2017/01/06 Python
Python操作word常见方法示例【win32com与docx模块】
2018/07/17 Python
Django 创建/删除用户的示例代码
2019/07/24 Python
用python实现英文字母和相应序数转换的方法
2019/09/18 Python
Python中关于浮点数的冷知识
2019/09/22 Python
Python实现隐马尔可夫模型的前向后向算法的示例代码
2019/12/31 Python
Python xlrd/xlwt 创建excel文件及常用操作
2020/09/24 Python
python实现图片,视频人脸识别(dlib版)
2020/11/18 Python
python使用smtplib模块发送邮件
2020/12/17 Python
HTML块级标签汇总(小篇)
2016/07/13 HTML / CSS
Hotels.com日本:国外和海外住宿,酒店预订
2019/12/13 全球购物
SK-II神仙水美国官网:SK-II美国
2020/02/25 全球购物
户外婚礼策划方案
2014/02/08 职场文书
策划总监岗位职责
2014/02/16 职场文书
工厂门卫岗位职责范本
2014/04/04 职场文书
PyTorch 实现L2正则化以及Dropout的操作
2021/05/27 Python
带你了解CSS基础知识,样式
2021/07/21 HTML / CSS
Python3使用Qt5来实现简易的五子棋小游戏
2022/05/02 Python