Python实现简单多线程任务队列

最近我在用梯度下降算法绘制神经网络的数据时,遇到了一些算法性能的问题。梯度下降算法的代码如下(伪代码):

def gradient_descent():  # the gradient descent code  plotly.write(X, Y)

登录后复制

一般来说,当网络请求 plot.ly 绘图时会阻塞等待返回,于是也会影响到其他的梯度下降函数的执行速度。

一种解决办法是每调用一次 plotly.write 函数就开启一个新的线程,但是这种方法感觉不是很好。 我不想用一个像 cerely(一种分布式任务队列)一样大而全的任务队列框架,因为框架对于我的这点需求来说太重了,并且我的绘图也并不需要 redis 来持久化数据。

那用什么办法解决呢?我在 python 中写了一个很小的任务队列,它可以在一个单独的线程中调用 plotly.write函数。下面是程序代码。

from threading import Threadimport Queue import timeclass TaskQueue(Queue.Queue):

登录后复制

首先我们继承 Queue.Queue 类。从 Queue.Queue 类可以继承 get 和 put 方法,以及队列的行为。

立即学习“Python免费学习笔记(深入)”;

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 Threadimport Queueimport timeclass TaskQueue(Queue.Queue):def __init__(self, num_workers=1):Queue.Queue.__init__(self)self.num_workers = num_workersself.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 = Truet.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 doneprint "All done!"if __name__ == "__main__":tests()

登录后复制

版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌抄袭侵权/违法违规的内容, 请发送邮件至253000106@qq.com举报,一经查实,本站将立刻删除。

发布者:PHP中文网,转转请注明出处:https://www.chuangxiangniao.com/p/2535593.html

(0)
上一篇 2025年3月5日 23:00:09
下一篇 2025年3月5日 23:00:20

AD推荐 黄金广告位招租... 更多推荐

相关推荐

  • 深入解读Python解析XML的几种方式

    在xml解析方面,python贯彻了自己“开箱即用”(batteries included)的原则。在自带的标准库中,python提供了大量可以用于处理xml语言的包和工具,数量之多,甚至让python编程新手无从选择。 本文将介绍深入解读…

    2025年3月5日 编程技术
    100
  • python 网络爬虫初级实现代码

    首先,我们来看一个python抓取网页的库:urllib或urllib2。 那么urllib与urllib2有什么区别呢?可以把urllib2当作urllib的扩增,比较明显的优势是urllib2.urlopen()可以接受Request对…

    编程技术 2025年3月5日
    200
  • 如何在Python中编写并发程序

    GIL 在python中,由于历史原因(gil),使得python中多线程的效果非常不理想.gil使得任何时刻python只能利用一个cpu核,并且它的调度算法简单粗暴:多线程中,让每个线程运行一段时间t,然后强行挂起该线程,继而去运行其他…

    编程技术 2025年3月5日
    200
  • Python 多线程抓取图片效率对比

    目的: 是学习python 多线程的工作原理,及通过抓取400张图片这种IO密集型应用来查看多线程效率对比 import requestsimport urlparseimport osimport timeimport threading…

    编程技术 2025年3月5日
    200
  • python文件操作相关知识点总结整理

    本文汇总了python文件操作相关知识点。分享给大家供大家参考,具体如下: 总是记不住API。昨晚写的时候用到了这些,但是没记住,于是就索性整理一下吧: python中对文件、文件夹(文件操作函数)的操作需要涉及到os模块和shutil模块…

    编程技术 2025年3月5日
    200
  • Python 的描述符 descriptor详解

    python 在 2.2 版本中引入了descriptor(描述符)功能,也正是基于这个功能实现了新式类(new-styel class)的对象模型,同时解决了之前版本中经典类 (classic class) 系统中出现的多重继承中的 mr…

    编程技术 2025年3月5日
    200
  • python实现搜索本地文件信息写入文件的方法

    本文实例讲述了python实现搜索本地文件信息写入文件的方法。分享给大家供大家参考,具体如下: 主要功能: 在指定的盘符,如D盘,搜索出与用户给定后缀名(如:jpg,png)相关的文件,然后把搜索出来的信息(相关文件的绝对路径),存放到用户…

    2025年3月5日
    200
  • 12步教你理解Python装饰器

    通过下面的步骤让你由浅入深明白装饰器是什么。假定你拥有最基本的Python知识,本文阐述的东西可能对那些在工作中经常接触Python的人有很大的帮助。1、函数(Functions)在Python里,函数是用def关键字后跟一个函数名称和一个…

    编程技术 2025年3月5日
    200
  • python脚本设置系统时间的两种方法

    本文为大家分享了两种python脚本设置系统时间的方法,供大家参考,具体内容如下 第一种方法,使用Python设置系统时间,即给系统校时 #电脑时间用了一段时间后,系统时间不准了,想更新一下#在windows里面,更新系统时间,时常失败,而…

    编程技术 2025年3月5日
    200
  • python脚本设置超时机制系统时间的方法

    本文为大家介绍了python脚本设置系统时间的方法,一共有两种,其一是调用socket直接发送udp包到国家授时中心,其二是调用ntplib包。我在本地电脑ping 国家授时中心地址cn.pool.ntp.org有时出现丢包,然而,二者都没…

    2025年3月5日
    200

发表回复

登录后才能评论