1. #!/usr/bin/env python
  2. # -*- coding:utf-8 -*-
  3.  
  4. import queue
  5. import threading
  6. import contextlib
  7. import time
  8.  
  9. StopEvent = object()
  10.  
  11. class ThreadPool(object):
  12.  
  13. def __init__(self, max_num, max_task_num = None):
  14. if max_task_num:
  15. self.q = queue.Queue(max_task_num)
  16. else:
  17. self.q = queue.Queue()
  18. self.max_num = max_num
  19. self.cancel = False
  20. self.terminal = False
  21. self.generate_list = []
  22. self.free_list = []
  23.  
  24. def run(self, func, args, callback=None):
  25. """
  26. 线程池执行一个任务
  27. :param func: 任务函数
  28. :param args: 任务函数所需参数
  29. :param callback: 任务执行失败或成功后执行的回调函数,回调函数有两个参数1、任务函数执行状态;2、任务函数返回值(默认为None,即:不执行回调函数)
  30. :return: 如果线程池已经终止,则返回True否则None
  31. """
  32. if self.cancel:
  33. return
  34. if len(self.free_list) == 0 and len(self.generate_list) < self.max_num:
  35. self.generate_thread()
  36. w = (func, args, callback,)
  37. self.q.put(w)
  38.  
  39. def generate_thread(self):
  40. """
  41. 创建一个线程
  42. """
  43. t = threading.Thread(target=self.call)
  44. t.start()
  45.  
  46. def call(self):
  47. """
  48. 循环去获取任务函数并执行任务函数
  49. """
  50. current_thread = threading.currentThread()
  51. self.generate_list.append(current_thread)
  52.  
  53. event = self.q.get()
  54. while event != StopEvent:
  55.  
  56. func, arguments, callback = event
  57. try:
  58. result = func(*arguments)
  59. success = True
  60. except Exception as e:
  61. success = False
  62. result = None
  63.  
  64. if callback is not None:
  65. try:
  66. callback(success, result)
  67. except Exception as e:
  68. pass
  69.  
  70. with self.worker_state(self.free_list, current_thread):
  71. if self.terminal:
  72. event = StopEvent
  73. else:
  74. event = self.q.get()
  75. else:
  76.  
  77. self.generate_list.remove(current_thread)
  78.  
  79. def close(self):
  80. """
  81. 执行完所有的任务后,所有线程停止
  82. """
  83. self.cancel = True
  84. full_size = len(self.generate_list)
  85. while full_size:
  86. self.q.put(StopEvent)
  87. full_size -= 1
  88.  
  89. def terminate(self):
  90. """
  91. 无论是否还有任务,终止线程
  92. """
  93. self.terminal = True
  94.  
  95. while self.generate_list:
  96. self.q.put(StopEvent)
  97.  
  98. self.q.queue.clear()
  99.  
  100. @contextlib.contextmanager
  101. def worker_state(self, state_list, worker_thread):
  102. """
  103. 用于记录线程中正在等待的线程数
  104. """
  105. state_list.append(worker_thread)
  106. try:
  107. yield
  108. finally:
  109. state_list.remove(worker_thread)
  110.  
  111. # How to use
  112.  
  113. pool = ThreadPool(5)
  114.  
  115. def callback(status, result):
  116. # status, execute action status
  117. # result, execute action return value
  118. pass
  119.  
  120. def action(i):
  121. print(i)
  122.  
  123. for i in range(30):
  124. ret = pool.run(action, (i,), callback)
  125.  
  126. time.sleep(5)
  127. print(len(pool.generate_list), len(pool.free_list))
  128. print(len(pool.generate_list), len(pool.free_list))
  129. # pool.close()
  130. # pool.terminate()

线程池(优秀)

  1. #!/usr/bin/env python
  2. # -*- coding:utf-8 -*-
  3. import Queue
  4. import threading
  5.  
  6. class ThreadPool(object):
  7.  
  8. def __init__(self, max_num=20):
  9. self.queue = Queue.Queue(max_num)
  10. for i in xrange(max_num):
  11. self.queue.put(threading.Thread)
  12.  
  13. def get_thread(self):
  14. return self.queue.get()
  15.  
  16. def add_thread(self):
  17. self.queue.put(threading.Thread)
  18.  
  19. """
  20. pool = ThreadPool(10)
  21.  
  22. def func(arg, p):
  23. print arg
  24. import time
  25. time.sleep(2)
  26. p.add_thread()
  27.  
  28. for i in xrange(30):
  29. thread = pool.get_thread()
  30. t = thread(target=func, args=(i, pool))
  31. t.start()
  32. """

转载
作者:武沛齐 
出处:http://www.cnblogs.com/wupeiqi/

python-线程池的两种实现方式 【转载】的更多相关文章

  1. 【C#多线程】2.线程池简述+两种传统的异步模式

    线程池简述+两种传统的异步编程模式 1.线程池简述 首先我们要明确一点,编程中讲的线程与平时我们形容CPU几核几线程中的线程是不一样的,CPU线程是指逻辑处理器,比如4核8线程,讲的是这个cpu有8个 ...

  2. Android 应用开发 之通过AsyncTask与ThreadPool(线程池)两种方式异步加载大量数据的分析与对比--转载

     在加载大量数据的时候,经常会用到异步加载,所谓异步加载,就是把耗时的工作放到子线程里执行,当数据加载完毕的时候再到主线程进行UI刷新.在数据量非常大的情况下,我们通常会使用两种技术来进行异步加载,一 ...

  3. Java 中线程池的 7 种创建方式!

    在 Java 语言中,并发编程都是通过创建线程池来实现的,而线程池的创建方式也有很多种,每种线程池的创建方式都对应了不同的使用场景,总体来说线程池的创建可以分为以下两类: 通过 ThreadPoolE ...

  4. java中线程池的几种实现方式

    1.线程池简介:    多线程技术主要解决处理器单元内多个线程执行的问题,它可以显著减少处理器单元的闲置时间,增加处理器单元的吞吐能力.        假设一个服务器完成一项任务所需时间为:T1 创建 ...

  5. Java线程池的四种创建方式

    Java通过Executors提供四种线程池,分别为:newCachedThreadPool创建一个可缓存线程池,如果线程池长度超过处理需要,可灵活回收空闲线程,若无可回收,则新建线程. newFix ...

  6. python中的字典两种遍历方式

    dic = {"k1":"v1", "k2":"v2"} for k in dic: print(dic[K]) for ...

  7. python线程池示例

    使用with方式创建线程池,任务执行完毕之后,会自动关闭资源 , 否则就需要手动关闭线程池资源  import threading, time from concurrent.futures impo ...

  8. python 多线程两种实现方式,Python多线程下的_strptime问题,

    python 多线程两种实现方式 原创 Linux操作系统 作者:杨奇龙 时间:2014-06-08 20:24:26  44021  0 目前python 提供了几种多线程实现方式 thread,t ...

  9. day2 编程语言介绍、Python运行程序的两种方式、变量

    一 编程语言介绍 1. 机器语言 用计算机能理解的二进制指令直接编写程序,直接控制硬件 2. 汇编语言 用英文标签取代二进制指令编写程序,本质也是直接控制硬件 3. 高级语言 用人能理解的表达方式去编 ...

随机推荐

  1. 0216 aop和打印数据库执行日志

    需求 maven依赖 <dependency> <groupId>p6spy</groupId> <artifactId>p6spy</artif ...

  2. linux切换普通用户遇bash-4.1解决

    1,修改vim  /etc/passwd 把对应用户的登陆环境改成,/bin/bash 2,复制配置 cp -a /etc/skel/. /home/www/ 3再次尝试su www有效

  3. pve apt-get update error 升级报错-文章未完工和验证

    pve: apt-get update error 升级报错 提示如下报错 Hit: http://security.debian.org buster/updates InRelease Hit: ...

  4. MonkeyRunner Mac环境 录制脚本和回放 批量回放

    1.MonkeyRunner是AndroidSDK自带的一个东西,在SDK目录中的tools\bin文件夹中 2.配置环境变量 编辑环境变量:打开终端输入:open ~/.bash_profile 将 ...

  5. P4562 [JXOJ2018]游戏

    题目描述 她长大以后创业了,开了一个公司. 但是管理公司是一个很累人的活,员工们经常背着可怜偷懒,可怜需要时不时对办公室进行检查. 可怜公司有 n 个办公室,办公室编号是 l 到 l+n−1 ,可怜会 ...

  6. eclipse sql server 导出excel文件

    Jxl.jar 访问Excel的Jar包 注意:支持以.xls结尾的Excel文件,可能不支持.xlsx结尾的 下载地址: 程序所需要得包: 程序代码: package partice; import ...

  7. pyautocad

    首部必须 #!/usr/bin/env python # -*- coding: utf-8 -*- 导入pyautocad import pyautocad import re # 设置python ...

  8. 关于BaiduPSC-Go的一些bug的更正

    首先说下操作步骤 下载是在GutHub,这个不赘述,网上很多资料 下载之后配置环境变量,在path的后面加上一个分号,然后加上你下载的目录,目录名最好为英文 然后通过命令行CMD工具,输入BaiduP ...

  9. 使用c#做前台页面

    1.有很多组件,组件右属性,事件 2.在table中,操作用的是图片 3.打开dialog时,其他窗体不能使用 4.在子窗体编辑完,对后台操作后,在父窗体加载一下数据

  10. 百炼OJ - 1002 - 方便记忆的电话号码

    题目链接 思路 开个一千万的数组计数,最后遍历即可. #include<stdio.h> #include<string.h> #include<algorithm> ...