Python实现简单多线程任务队列
2016-02-27 00:00
1131 查看
最近我在用梯度下降算法绘制神经网络的数据时,遇到了一些算法性能的问题。梯度下降算法的代码如下(伪代码):
一般来说,当网络请求 plot.ly 绘图时会阻塞等待返回,于是也会影响到其他的梯度下降函数的执行速度。
一种解决办法是每调用一次 plotly.write 函数就开启一个新的线程,但是这种方法感觉不是很好。 我不想用一个像 cerely(一种分布式任务队列)一样大而全的任务队列框架,因为框架对于我的这点需求来说太重了,并且我的绘图也并不需要 redis 来持久化数据。
那用什么办法解决呢?我在 python 中写了一个很小的任务队列,它可以在一个单独的线程中调用 plotly.write函数。下面是程序代码。
首先我们继承 Queue.Queue 类。从 Queue.Queue 类可以继承 get 和 put 方法,以及队列的行为。
初始化的时候,我们可以不用考虑工作线程的数量。
我们把 task, args, kwargs 以元组的形式存储在队列中。*args 可以传递数量不等的参数,**kwargs 可以传递命名参数。
我们为每个 worker 创建一个线程,然后在后台删除。
下面是 worker 函数的代码:
worker 函数获取队列顶端的任务,并根据输入参数运行,除此之外,没有其他的功能。下面是队列的代码:
我们可以通过下面的代码测试:
Blokkah 是我们要做的任务名称。队列已经缓存在内存中,并且没有执行很多任务。下面的步骤是把主队列当做单独的进程来运行,这样主程序退出以及执行数据库持久化时,队列任务不会停止运行。但是这个例子很好地展示了如何从一个很简单的小任务写成像工作队列这样复杂的程序。
修改之后,我的梯度下降算法工作效率似乎更高了。如果你很感兴趣的话,可以参考下面的代码。
Python多线程编程(五):死锁的形成
Python多线程编程(四):使用Lock互斥锁
Python中多线程及程序锁浅析
python多线程threading.Lock锁用法实例
python线程锁(thread)学习示例
Python 多线程抓取图片效率对比
Python多线程、异步+多进程爬虫实现代码
Python中使用Queue和Condition进行线程同步的方法
简要讲解Python编程中线程的创建与锁的使用
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多线程编程(六):可重入锁RLockPython多线程编程(五):死锁的形成
Python多线程编程(四):使用Lock互斥锁
Python中多线程及程序锁浅析
python多线程threading.Lock锁用法实例
python线程锁(thread)学习示例
Python 多线程抓取图片效率对比
Python多线程、异步+多进程爬虫实现代码
Python中使用Queue和Condition进行线程同步的方法
简要讲解Python编程中线程的创建与锁的使用
相关文章推荐
- python的else子句使用指南
- 用python写的一个wordpress的采集程序
- python学习之编写查询ip程序
- 学习python 之编写简单乘法运算题
- 学习python之编写简单乘法口诀表实现代码
- 学习python之编写简单简单连接数据库并执行查询操作
- Python数据库的连接实现方法与注意事项
- 用Python做的数学四则运算_算术口算练习程序(后添加减乘除)
- Pythont特殊语法filter,map,reduce,apply使用方法
- python PIL模块与随机生成中文验证码
- python中input()与raw_input()的区别分析
- python中map()与zip()操作方法
- python操作mysql
- [Leetcode]220. Contains Duplicate III @python
- 笨办法学python_学习笔记2
- python之干什么可以走的路线
- 《python基础教程》第一章 基础知识
- python做量化交易干货分享
- Python并发执行
- Python学习笔记(二) 装饰器decorator