python多线程抽象编程模型详解


Posted in Python onMarch 20, 2019

最近需要完成一个多线程下载的工具,对其中的多线程下载进行了一个抽象,可以对所有需要使用到多线程编程的地方统一使用这个模型来进行编写。

主要结构:

1、基于Queue标准库实现了一个类似线程池的工具,用户指定提交任务线程submitter与工作线程worker数目,所有线程分别设置为后台运行,提供等待线程运行完成的接口。

2、所有需要完成的任务抽象成task,提供单独的无参数调用方式,供worker线程调用;task以生成器的方式作为参数提供,供submitter调用。

3、所有需要进行线程交互的信息放在context类中。

主要实现代码如下:

#Submitter线程类实现,主要是`task_generator`调用
class SubmitterThread(threading.Thread):
  _DEFAULT_WAIT_TIMEOUT = 2 #seconds
  def __init__(self, queue, task_gen, timeout=2):
    super(SubmitterThread, self).__init__()
    self.queue = queue
    if not isinstance(timeout, int):
      _logger.error('Thread wait timeout value error: %s, '
             'use default instead.' % timeout)
      self.timeout = self._DEFAULT_WAIT_TIMEOUT
    self.timeout = timeout
    self.task_generator = task_gen

  def run(self):
    while True:
      try:
        task = self.task_generator.next()
        self.queue.put(task, True, self.timeout)
      except Queue.Full:
        _logger.debug('Task queue is full. %s wait %d second%s timeout' %
               (self.name, self.timeout, 's' if (self.timeout > 1) else ''))
        break
      except (StopIteration, ValueError) as e:
        _logger.debug('Task finished')
        break
#Worker线程实现,主要就是try块内的func调用
class WorkerThread(threading.Thread):
  _DEFAULT_WAIT_TIMEOUT = 2 #seconds
  def __init__(self, queue, timeout=2):
    super(WorkerThread, self).__init__()
    self.queue = queue
    if not isinstance(timeout, int):
      _logger.error('Thread wait timeout value error: %s, '
             'use default instead.' % timeout)
      self.timeout = self._DEFAULT_WAIT_TIMEOUT
    self.timeout = timeout

  def run(self):
    while True:
      try:
        func = self.queue.get(True, self.timeout)
      except Queue.Empty:
        _logger.debug('Task queue is empty. %s wait %d second%s timeout' %
               (self.name, self.timeout, 's' if (self.timeout > 1) else ''))
        break

      if not callable(func):
        time.sleep(1)
      try:
        func()
      except Exception as e:
        _logger.error('Thread %s running occurs error: %s' %
               (self.name, e))
        print('Thread running error: %s' % e)
class Executor(object):
  """
  The really place to execute executor
  """
  thread_list = []
  submitters = 0
  workers = 0
  queue = None
  task_generator = None
  timeout = 0
  def __init__(self, task_gen, submitters=1, workers=1 , timeout=2):
    if len(self.thread_list) != 0:
      raise RuntimeError('Executor can only instance once.')
    self.queue = Queue.Queue(maxsize=submitters * 2 + workers * 2)
    self.submitters = submitters
    self.workers = workers
    self.task_generator = task_gen
    self.timeout = timeout

  def start(self):
    for i in range(self.submitters):
      submitter = SubmitterThread(self.queue, self.task_generator, self.timeout)
      self.thread_list.append(submitter)
      submitter.setName('Submitter-%d' % i)
      submitter.setDaemon(True)
      submitter.start()
    for i in range(self.workers):
      worker = WorkerThread(self.queue, self.timeout)
      self.thread_list.append(worker)
      worker.setName('Worker-%d' % i)
      worker.setDaemon(True)
      worker.start()

  def is_alive(self):
    alive = False
    for t in self.thread_list:
      if t.isAlive():
        alive = True
        break
    return alive

  def wait_to_shutdown(self):
    _logger.debug('Start to wait to shutdown')
    for t in self.thread_list:
      t.join()
      _logger.debug('Shutdown thread : %s' % t.name)

Executor类保存了线程池,提供相应接口。有了这个抽象之后,只需要实例化Executor类的对象,然后调用start方法进行多线程任务的运行。并可以用is_alive等接口再主线程内进行其他处理。

后续再使用这个抽象进行实际多线程任务的实现。

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持三水点靠木。

Python 相关文章推荐
Python随手笔记第一篇(2)之初识列表和元组
Jan 23 Python
Python创建字典的八种方式
Feb 27 Python
python安装pil库方法及代码
Jun 25 Python
Python实现把类当做字典来访问
Dec 16 Python
Python安装tar.gz格式文件方法详解
Jan 19 Python
python中upper是做什么用的
Jul 20 Python
Python pexpect模块及shell脚本except原理解析
Aug 03 Python
浅谈Python3中print函数的换行
Aug 05 Python
python实现单机五子棋
Aug 28 Python
Python中的流程控制详解
Feb 18 Python
python使用matplotlib绘制图片时x轴的刻度处理
Aug 30 Python
详解Golang如何实现支持随机删除元素的堆
Sep 23 Python
基于python生成器封装的协程类
Mar 20 #Python
python实现栅栏加解密 支持密钥加密
Mar 20 #Python
python实现Virginia无密钥解密
Mar 20 #Python
python实现维吉尼亚加密法
Mar 20 #Python
Python multiprocess pool模块报错pickling error问题解决方法分析
Mar 20 #Python
python实现对输入的密文加密
Mar 20 #Python
python实现字符串加密成纯数字
Mar 19 #Python
You might like
php中的注释、变量、数组、常量、函数应用介绍
2012/11/16 PHP
php each 返回数组中当前的键值对并将数组指针向前移动一步实例
2016/11/22 PHP
jQuery lazyload 的重复加载错误以及修复方法
2010/11/19 Javascript
javascript parseInt() 函数的进制转换注意细节
2013/01/08 Javascript
快速学习jQuery插件 Form表单插件使用方法
2015/12/01 Javascript
总结javascript三元运算符知识点
2018/09/28 Javascript
vue input实现点击按钮文字增删功能示例
2019/01/29 Javascript
vue中img src 动态加载本地json的图片路径写法
2019/04/25 Javascript
关于layui 弹出层一闪而过就消失的解决方法
2019/09/09 Javascript
JS实现小星星特效
2019/12/24 Javascript
js实现表格单列按字母排序
2020/08/12 Javascript
VUE异步更新DOM - 用$nextTick解决DOM视图的问题
2020/11/06 Javascript
python实现目录树生成示例
2014/03/28 Python
python装饰器与递归算法详解
2016/02/18 Python
利用Django内置的认证视图实现用户密码重置功能详解
2017/11/24 Python
详解用Python处理HTML转义字符的5种方式
2017/12/27 Python
详解用Python练习画个美队盾牌
2019/03/23 Python
python的内存管理和垃圾回收机制详解
2019/05/18 Python
用Python抢火车票的简单小程序实现解析
2019/08/14 Python
利用python对mysql表做全局模糊搜索并分页实例
2020/07/12 Python
Python3如何在服务器打印资产信息
2020/08/27 Python
Python使用内置函数setattr设置对象的属性值
2020/10/16 Python
Django 实现图片上传和下载功能
2020/12/31 Python
35款精致的 CSS3 和 HTML5 网页模板 推荐
2012/08/03 HTML / CSS
amazeui页面校验功能的实现代码
2020/08/24 HTML / CSS
Expedia英国:全球最大的在线旅游公司
2017/09/07 全球购物
护理专业推荐信
2013/11/07 职场文书
普通大学毕业生自荐信范文
2014/02/23 职场文书
捐款倡议书格式范文
2014/05/14 职场文书
药剂专业求职信
2014/06/20 职场文书
2014党员民主评议个人总结
2014/09/10 职场文书
总经理司机岗位职责
2015/04/10 职场文书
家长意见和建议怎么写
2015/06/04 职场文书
安全生产隐患排查制度
2015/08/05 职场文书
详细了解MVC+proxy
2021/07/09 Java/Android
面试中canvas绘制图片模糊图片问题处理
2022/03/13 Javascript