"""
思路
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. web3调用call()方法获取不到返回值

    一.web3的call()获取不到返回值问题和解决方法 在彩票小合约中,遇到一个问题:合约中 有两个方法 第一个返回一个账户地址,没有使用到当前方法调用者信息: 第二个使用到了当前方法调用者信息 在w ...

  2. (转)Cognos的下载地址分享

    原文:https://blog.csdn.net/Wikey_Zhang/article/details/76138965 刚开始接触Cognos,发现Cognos真是一款挺不错的报表工具,先分享一下 ...

  3. c++中double类型控制小数位数

    有时,我们需要输出确定小数位数的double,可以先引入如下头文件: #include <iomanip> 然后通过下列方式输出: double zzz = 8.66666; cout & ...

  4. 使用makefile

    最近在学习一个处理二维相场问题的c++程序,遇到了makefile文件,之前没有接触过,这里做一个简单的整理. 什么是makefile? 大多程序员使用的windows操作系统,IED都完成了make ...

  5. c++中堆、栈、自由存储区和常量存储区(转)

    代码段 --text(code segment/text segment)text段在内存中被映射为只读,但.data和.bss是可写的.text段是程序代码段,在AT91库中是表示程序段的大小,它是 ...

  6. Javascript图片预加载详解 分类: JavaScript HTML+CSS 2015-05-29 11:01 768人阅读 评论(0) 收藏

    预加载图片是提高用户体验的一个很好方法.图片预先加载到浏览器中,访问者便可顺利地在你的网站上冲浪,并享受到极快的加载速度.这对图片画廊及图片占据很大比例的网站来说十分有利,它保证了图片快速.无缝地发布 ...

  7. CDN基本工作过程

    看了一些介绍CDN的文章,感觉这篇是讲的最清楚的. 使用CDN会极大地简化网站的系统维护工作量,网站维护人员只需将网站内容注入CDN的系统,通过CDN部署在各个物理位置的服务器进行全网分发,就可以实现 ...

  8. Shell脚本 | 性能测试之启动时间

    安卓应用的性能测试,通常包括六个指标:启动时间.内存.CPU.耗电量.流量.流畅度. 除了耗电量,其他五个指标的数据在我们团队中已经可以通过运行脚本的方式获取到. 今天给大家分享下启动时间的脚本吧- ...

  9. SQL 语句语法简介(一)

    语句分类 SQL 命令一般分为三类:DQL.DML.DDL. 一.DDL语句. 1.1建表语句 CREATE TABLE table_name( col01_name data_type, col02 ...

  10. Hibernate关联关系映射之一对一(主键关联)

    在业务成的域模型中,类和类之间最普遍的关系就是关联关系,而关联也是有方向的. 就以例子来说明:一个人对应一张身份证.对其进行增删改. 对于人在数据创建表的时候,我们就给他两个字段,一个是id号,一个就 ...