Python实现简单多线程任务队列
作者:hebedich 发布时间:2022-07-29 13:21:43
最近我在用梯度下降算法绘制神经网络的数据时,遇到了一些算法性能的问题。梯度下降算法的代码如下(伪代码):
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编程中使用这几个函数来简化我们的编程工作,经常使用能使编程效率大大地提高。1. Map 函数map函数可以使用另外一个函
- 说明:糗事百科段子的爬取,采用了队列和多线程的方式,其中关键点是Queue.task_done()、Queue.join(),保证了线程的有
- 先给大家展示下效果图,大家感觉不错,请参考实现代码:实现原理:点击按钮,往需要动画的div中添加或移除拥有动画效果的class。由于微信小程
- centos下安装配置phpmyadmin,我花了二个晚上,郁闷的我不行,配置phpmyadmin简单吧,很简单,我刚工作的时候,就配置过,
- 对于数据库管理员来说,可以经常想了解一些之前未听说过的存储过程,特别是无文档类型的存储过程。或许是用这些存储过程,能够简化日常的数据管理。为
- 字符串转list数组str = '1,2,3'arr = str.split(',')gpu_ids分配na
- 动态展示这是一个动态图哦导读兄弟们可以收藏一下哦!情人节可以送出去,肥学找了几朵python写的花给封装好送给大家。不是多炫酷但是有足够的用
- 选择最实用来谈一下首先,你要慎重选择你就业的城市。这点是目前多数人都忽略的重要因素。无论你的设计思路和发展方向都要依托你所在城市来作为载体。
- 一、Pytorch distributed 多卡并行载入模型这次来介绍下如何载入模型。目前没有找到官方的distribute 载入模型的方式
- 本文实例讲述了PHP实现的简单排列组合算法应用。分享给大家供大家参考,具体如下:一、问题:给你一个40斤的西瓜,给3个人分,有多少种分法?二
- 将数据写入Excel文件中,用python实现起来非常的简单,下面一步步地教大家。一、导入excel表格文件处理函数import xlwt注
- 一、图像缩略图的编辑图像的缩略图是指把图像按原比例缩小,可作为原图的预览,这在网络速度比较慢时可快速地显示图片的概图。当你的网页上有大型图片
- 下面是列表合并的4种方法,其中的代码都在Python3下测试通过,在Python2下运行应该也没问题,时间关系就没测试,遇到问题可以联系小编
- 需求:给定一个dataframe和一个list,list中存放的是dataframe中某一列的元素,删除dataframe中与list元素重
- PDO::queryPDO::query — 执行 SQL 语句,返回PDOStatement对象,可以理解为结果集(PHP 5 >=
- 一个简单但功能比较完善的自动生成缩略图的函数,可以按需要对图片进行缩放、裁切、锁定宽或高、使用空白填充以下为源码,比较简单,相信很容易看明白
- 本文通过Python3+pyqt5实现了python Qt GUI 快速编程的19章的页面索引器应用程序例子。/home/yrd/eric_
- 在软件开发过程中经常会遇到数据库升迁的问题,原因比较多,如acsess访问速度比sql server慢、删除数据记录后access会留下空档
- 点乘import torchx = torch.tensor([[3,3],[3,3]])y = x*x #x.dot(x)z = torc
- 今天好友问我怎么从阿里云服务器上把文件下载下来。我一听之下觉得办法很多啊,随意搭个服务器,然后把文件一丢就可以下载了;弄个FTP也行;直接用