"""
思路
1,将任务放在队列
1)创建队列:(初始化)
2)设置大小,线程池的最大容量
3)真实创建的线程 列表
4)空闲的线程数量 2,着手开始处理任务
1)创建线程
2)空闲线程数量大于0,则不再创建线程
3)创建线程池的数量 不能高于线程池的限制
4)根据任务个数判断 创建线程的数量
2)线程去队列中取任务
1)取任务包(任务包是一个元祖)
2)任务为空时,不再取(终止)
""" import time
import threading
import queue stopEvent = object() # 停止任务的标志 class ThreadPool(object):
def __init__(self, max_thread):
# 创建任务队列,可以放无限个任务
self.queue = queue.Queue()
# 指定最大线程数
self.max_thread = max_thread
# 停止标志
self.terminal = False
# 创建真实线程数
self.generate_list = []
# 空闲线程数
self.free_thread = [] def run(self, action, args, callback=None):
"""
线程池执行一个任务
:param action:任务函数
:param args:任务参数
:param callback:执行完任务的回调函数,成功或者失败的返回值。
:return:
"""
# 线程池运行的条件:1)
if len(self.free_thread) == 0 and len(self.generate_list) < self.max_thread:
self.generate_thread()
task = (action, args, callback)
self.queue.put(task) def callback(self):
"""
回调函数:循环取获取任务,并执行任务函数
:return:
"""
# 获取当前线程
current_thread = threading.current_thread()
self.generate_list.append(current_thread)
# 取任务并执行
event = self.queue.get()
# 事件类型是任务
while event != stopEvent: # 重点是这个判断 使任务终止
# 解开任务包 ,(任务是一个元祖)
# 执行任务
# 标记:执行任务前的状态,执行任务后的状态
action, args, callback = event
try:
ret = action(*args)
success = True
except Exception as x:
success = False
ret = x
if callback is not None:
try:
callback(success, ret)
except Exception as e:
print(e)
else:
pass
if not self.terminal:
self.free_thread.append(current_thread)
event = self.queue.get()
self.free_thread.remove(current_thread)
else:
# 停止进行取任务
event = stopEvent
else:
# 不是元祖,不是任务,则清空当前线程,不在去取任务
self.generate_list.remove(current_thread) def generate_thread(self):
"""
创建一个线程
:return:
"""
t = threading.Thread(target=self.callback)
t.start() # 终止取任务
def terminals(self):
"""
无论是否还有任务,终止线程
:return:
"""
self.terminal = True def close(self):
"""
执行完所有的任务后,所有线程停止
:return:
"""
num = len(self.generate_list)
self.queue.empty()
while num:
self.queue.put(stopEvent)
num -= 1 def test(pi):
time.sleep(0.5)
print(pi) pool = ThreadPool(10) for i in range(100):
pool.run(action=test, args=(i,)) pool.terminals()
pool.close()

Python 自定义线程池的更多相关文章

  1. python自定义线程池

    关于python的多线程,由与GIL的存在被广大群主所诟病,说python的多线程不是真正的多线程.但多线程处理IO密集的任务效率还是可以杠杠的. 我实现的这个线程池其实是根据银角的思路来实现的. 主 ...

  2. python---基础知识回顾(十)进程和线程(py2中自定义线程池和py3中的线程池使用)

    一:自定义线程池的实现 前戏: 在进行自定义线程池前,先了解下Queue队列 队列中可以存放基础数据类型,也可以存放类,对象等特殊数据类型 from queue import Queue class ...

  3. Android线程管理之ThreadPoolExecutor自定义线程池

    前言: 上篇主要介绍了使用线程池的好处以及ExecutorService接口,然后学习了通过Executors工厂类生成满足不同需求的简单线程池,但是有时候我们需要相对复杂的线程池的时候就需要我们自己 ...

  4. Android AsyncTask 深度理解、简单封装、任务队列分析、自定义线程池

    前言:由于最近在做SDK的功能,需要设计线程池.看了很多资料不知道从何开始着手,突然发现了AsyncTask有对线程池的封装,so,就拿它开刀,本文将从AsyncTask的基本用法,到简单的封装,再到 ...

  5. Android 自定义线程池的实战

    前言:在上一篇文章中我们讲到了AsyncTask的基本使用.AsyncTask的封装.AsyncTask 的串行/并行线程队列.自定义线程池.线程池的快速创建方式. 对线程池不了解的同学可以先看 An ...

  6. c#网络通信框架networkcomms内核解析之十 支持优先级的自定义线程池

    NetworkComms网络通信框架序言 本例基于networkcomms2.3.1开源版本  gplv3协议 如果networkcomms是一顶皇冠,那么CommsThreadPool(自定义线程池 ...

  7. 介绍开源的.net通信框架NetworkComms框架 源码分析(十五 ) CommsThreadPool自定义线程池

    原文网址: http://www.cnblogs.com/csdev Networkcomms 是一款C# 语言编写的TCP/UDP通信框架  作者是英国人  以前是收费的 目前作者已经开源  许可是 ...

  8. 一个自定义线程池的小Demo

    在项目中如果是web请求时候,IIS会自动分配一个线程来进行处理,如果很多个应用程序共享公用一个IIS的时候,线程分配可能会出现一个问题(当然也是我的需求造成的) 之前在做项目的时候,有一个需求,就是 ...

  9. C#自定义线程池

    自定义线程池-c#的简单实现 下面是代码,希望大家提出更好的建议: 1.ThreadManager.cs using System; using System.Threading; using Sys ...

随机推荐

  1. typescript-koa-postgresql 实现一个简单的rest风格服务器 —— 连接 postgresql 数据库

    接上一篇,这里使用 sequelize 来连接 postgresql 数据库 1.安装 sequelize,数据库驱动 pg yarn add sequelize sequelize-typescri ...

  2. the fist blood of java-eclipse 哈哈哈哈 封装的运用

    class Student {    private int id;    public String name;    public String sex;    private int score ...

  3. Django Admin实现三级联动(省市区)

    通过自定义Admin的模板文件实现省市区的三级联动.要求创建记录时,根据省>市>区的顺序选择依次显示对应数据. 修改记录时默认显示已存在的数据. Model class Member(mo ...

  4. python可变对象与不可变对象的差别

    一.可变对象和不可对象 Python在heap中分配的对象分成两类:可变对象和不可对象.所谓可变对象是指,对象的内容可变,而不可变对象是指内容不可变.   不可变对象:int.string.float ...

  5. 客户端禁用cookie

    如果客户端禁用cookie的话不影响session使用 的设置方法: <sessionState     cookieless="AutoDetect"

  6. Git学习系列之Debian或Ubuntu上安装Git详细步骤(图文详解)

    前言 最早Git是在Linux上开发的,很长一段时间内,Git也只能在Linux和Unix系统上跑.不过,慢慢地有人把它移植到了Windows上.现在,Git可以在Linux.Unix.Mac和Win ...

  7. Redis开发与运维

    常用命令 redis-server启动redis redis-server /opt/redis/redis.conf    配置启动 redis-server --port 6379 --dir / ...

  8. Tomcat学习总结(12)—— Tomcat集群配置

    现目前基于javaWeb开发的应用系统已经比比皆是,尤其是电子商务网站,要想网站发展壮大,那么必然就得能够承受住庞大的网站访问量:大家知道如果服务器访问量过大,就会出现服应用务器崩溃的情况,这个时候怎 ...

  9. Nginx range filter模块数字错误漏洞修复 (Nginx平滑升级)

    对线上生产环境服务器进行漏洞扫描, 发现有两台前置机器存在Nginx range filter模块数字错误漏洞, 当使用nginx标准模块时,攻击者可以通过发送包含恶意构造range域的header ...

  10. linux sticky

    文件的粘滞位(sticky)位是作什么用的? 普通文件的sticky位会被linux内核忽略, 目录的sticky位表示这个目录里的文件只能被owner和root删除 粘着位(Sticky bit) ...