#!/usr/bin/env python
# -*- coding:utf-8 -*- import queue
import threading
import contextlib
import time StopEvent = object() class ThreadPool(object): def __init__(self, max_num, max_task_num = None):
if max_task_num:
self.q = queue.Queue(max_task_num)
else:
self.q = queue.Queue()
self.max_num = max_num
self.cancel = False
self.terminal = False
self.generate_list = []
self.free_list = [] def run(self, func, args, callback=None):
"""
线程池执行一个任务
:param func: 任务函数
:param args: 任务函数所需参数
:param callback: 任务执行失败或成功后执行的回调函数,回调函数有两个参数1、任务函数执行状态;2、任务函数返回值(默认为None,即:不执行回调函数)
:return: 如果线程池已经终止,则返回True否则None
"""
if self.cancel:
return
if len(self.free_list) == 0 and len(self.generate_list) < self.max_num:
self.generate_thread()
w = (func, args, callback,)
self.q.put(w) def generate_thread(self):
"""
创建一个线程
"""
t = threading.Thread(target=self.call)
t.start() def call(self):
"""
循环去获取任务函数并执行任务函数
"""
current_thread = threading.currentThread()
self.generate_list.append(current_thread) event = self.q.get()
while event != StopEvent: func, arguments, callback = event
try:
result = func(*arguments)
success = True
except Exception as e:
success = False
result = None if callback is not None:
try:
callback(success, result)
except Exception as e:
pass with self.worker_state(self.free_list, current_thread):
if self.terminal:
event = StopEvent
else:
event = self.q.get()
else: self.generate_list.remove(current_thread) def close(self):
"""
执行完所有的任务后,所有线程停止
"""
self.cancel = True
full_size = len(self.generate_list)
while full_size:
self.q.put(StopEvent)
full_size -= 1 def terminate(self):
"""
无论是否还有任务,终止线程
"""
self.terminal = True while self.generate_list:
self.q.put(StopEvent) self.q.queue.clear() @contextlib.contextmanager
def worker_state(self, state_list, worker_thread):
"""
用于记录线程中正在等待的线程数
"""
state_list.append(worker_thread)
try:
yield
finally:
state_list.remove(worker_thread) # How to use pool = ThreadPool(5) def callback(status, result):
# status, execute action status
# result, execute action return value
pass def action(i):
print(i) for i in range(30):
ret = pool.run(action, (i,), callback) time.sleep(5)
print(len(pool.generate_list), len(pool.free_list))
print(len(pool.generate_list), len(pool.free_list))
# pool.close()
# pool.terminate()

线程池(优秀)

 #!/usr/bin/env python
# -*- coding:utf-8 -*-
import Queue
import threading class ThreadPool(object): def __init__(self, max_num=20):
self.queue = Queue.Queue(max_num)
for i in xrange(max_num):
self.queue.put(threading.Thread) def get_thread(self):
return self.queue.get() def add_thread(self):
self.queue.put(threading.Thread) """
pool = ThreadPool(10) def func(arg, p):
print arg
import time
time.sleep(2)
p.add_thread() for i in xrange(30):
thread = pool.get_thread()
t = thread(target=func, args=(i, pool))
t.start()
"""

转载
作者:武沛齐 
出处: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. vue 项目初始化

    初始化 vue init webpack-simple myproject 安裝 npm install 运行 npm run dev 访问地址 http://localhost:8080/ 安装we ...

  2. Outlook365(Oulook2016 或2013) 写邮件输入收件人时的推荐联系人如何清理?

    · 在Outlook365(Oulook2016 或2013) 中写邮件,输入收件人邮箱地址时,会出现“最近联系人”  “其他建议”等推荐的联系人,可以方便选择.如果里面有很多邮箱地址的已经无效的话, ...

  3. WMITools修复wmi劫持--hao643.com/jtsh123劫持(修改快捷方式跳转至hao123.com)

    >症状:所有浏览器快捷方式,都被加上尾巴,例如IE的:"C:\Program Files\Internet Explorer\iexplore.exe" http://hao ...

  4. 题解【洛谷P1886】滑动窗口 /【模板】单调队列

    题面 单调队列模板题. 单调队列可以从队首和队尾出队. 队列中的元素大小具有一定的顺序. 具体可参考这一篇题解 #include <bits/stdc++.h> #define itn i ...

  5. 用户注册(php)login(非美化)

    <!DOCTYPE html><html> <head> <meta charset="UTF-8"> <title>& ...

  6. hdu2328 后缀树

    #include <cstdio> #include <cstdlib> #include <cstring> #include <cmath> #in ...

  7. 在Linux系统上安装Jenkins

    1.首先准备安装java环境,安装jdk 详情查看博客以,这里不做多介绍. 2.下载Jenkins至Linux服务器 查看内核版本信息:cat /proc/version uname -m cat / ...

  8. AcWing 148. 合并果子

    #include <iostream> #include <algorithm> #include <queue> using namespace std; int ...

  9. 1025 PAT Ranking (25分)

    1025 PAT Ranking (25分) 1. 题目 2. 思路 设置结构体, 先对每一个local排序,再整合后排序 3. 注意点 整体排序时注意如果分数相同的情况下还要按照编号排序 4. 代码 ...

  10. ansible笔记(5):常用模块之命令类模块

    1.command模块 它的作用是帮助我们在远程主机上执行命令. [注意]使用command模块在远程主机中执行命令时,不会经过远程主机的shell处理,在使用command模块时,如果需要执行的命令 ...