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 相关文章推荐
下载给定网页上图片的方法
Feb 18 Python
跟老齐学Python之网站的结构
Oct 24 Python
编写Python小程序来统计测试脚本的关键字
Mar 12 Python
window下eclipse安装python插件教程
Apr 24 Python
Python使用Scrapy保存控制台信息到文本解析
Dec 27 Python
Go/Python/Erlang编程语言对比分析及示例代码
Apr 23 Python
PIL图像处理模块paste方法简单使用详解
Jul 17 Python
python线程的几种创建方式详解
Aug 29 Python
python从zip中删除指定后缀文件(推荐)
Dec 05 Python
Pytorch 定义MyDatasets实现多通道分别输入不同数据方式
Jan 15 Python
python模块内置属性概念及实例
Feb 18 Python
Python爬取酷狗MP3音频的步骤
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
简单的页面缓冲技术
2006/10/09 PHP
PHP静态调用非静态方法的应用分析
2013/05/02 PHP
PHP实现的封装验证码类详解
2013/06/18 PHP
php selectradio和checkbox默认选择的实现方法详解
2013/06/29 PHP
使用PHP接受文件并获得其后缀名的方法
2015/08/05 PHP
javascript之querySelector和querySelectorAll使用说明
2011/10/09 Javascript
多个js与css文件的合并方法详细说明
2012/12/26 Javascript
node.js中的fs.lchown方法使用说明
2014/12/16 Javascript
JQuery中ajax方法访问web服务实例
2015/07/18 Javascript
WEB前端开发都应知道的jquery小技巧及jquery三个简写
2015/11/15 Javascript
JS失效 提示HTML1114: (UNICODE 字节顺序标记)的代码页 utf-8 覆盖(META 标记)的冲突的代码页 utf-8
2017/06/23 Javascript
vue事件修饰符和按键修饰符用法总结
2017/07/25 Javascript
浅谈React + Webpack 构建打包优化
2018/01/23 Javascript
基于游标的分页接口实现代码示例
2018/11/12 Javascript
微信小程序设置滚动条过程详解
2019/07/25 Javascript
layui对工具条进行选择性的显示方法
2019/09/19 Javascript
分享Angular http interceptors 拦截器使用(推荐)
2019/11/10 Javascript
Vue+Element UI 树形控件整合下拉功能菜单(tree + dropdown +input)
2020/08/28 Javascript
python解析文件示例
2014/01/23 Python
python3第三方爬虫库BeautifulSoup4安装教程
2018/06/19 Python
Python3基础教程之递归函数简单示例
2019/06/07 Python
Django2 连接MySQL及model测试实例分析
2019/12/10 Python
Python连接字符串过程详解
2020/01/06 Python
tensorflow中tf.reduce_mean函数的使用
2020/04/19 Python
利用python进行文件操作
2020/12/04 Python
Python爬虫后获取重定向url的两种方法
2021/01/19 Python
为什么需要版本控制
2016/10/28 面试题
构建高效课堂实施方案
2014/03/13 职场文书
2014年教师节座谈会发言稿
2014/09/10 职场文书
2014年班长个人工作总结
2014/11/14 职场文书
党员民主生活会材料
2014/12/15 职场文书
党支部创先争优公开承诺书
2015/04/30 职场文书
海上钢琴师的观后感
2015/06/11 职场文书
《别在吃苦的年纪选择安逸》读后感3篇
2019/11/30 职场文书
Python+Selenium实现读取网易邮箱验证码
2022/03/13 Python
Python安装及建立虚拟环境的完整步骤
2022/06/25 Servers