"""
思路
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. redis常用命令(二)

    一.集合(set) 单值多value,vaue不能重复 sadd/smembers/sismember 添加数据/获取set所有数据/判断是否存在某个值 scard 获取集合里面的元素个数 srem ...

  2. 解决SecureCRT/Xshell无法以root用户连接Ubuntu

    首先执行命令ps -e | grep ssh .查看是否有ssh进程运行. 确认没有ssh运行,且系统未安装openssh.   然后在系统终端界面内输入apt-get update命令. (确保系统 ...

  3. 理解web service 和 SOA

    什么是SOA? SOA的全称为Service Oriented Architecture,即面向服务架构.这是一种架构理念.它的提出是在企业计算领域将耦合的系统划分为松耦合的无状态的服务.服务发布出来 ...

  4. spring 后处理器

    Bean后处理器 新建maven项目并添加spring依赖,目录结构如下 Axe public interface Axe { public String chop(); } Person publi ...

  5. [个人项目] echarts 实现数据(tooltip)自动轮播插件

    前言 最近, 工作中要做类似这种的项目. 用到了百度的 echarts 这个开源的数据可视化的框架. 因为投屏项目不像PC端的WEB, 它不允许用户用鼠标键盘等交互. 有些图表只能看到各部分的占比情况 ...

  6. UTF-8和GBK编码的区别

    UTF-8:对英文使用8位(一个字节).中文使用24位(三个字节)编码.对于英文字符比较多的网站一般用utf-8来编码以节省空间:包含全世界所有国家需要用到的字符,其编码的蚊子可以在各国各种支持utf ...

  7. Chapter 3 Phenomenon——22

    He paused, and for a brief moment his stunning face was unexpectedly vulnerable. 他愣住了,然后一段时间他令人昏迷的脸变 ...

  8. docker内存和cpu调试

    本地启动了一个sshd的容器服务,但该容器经常会被重启导致ssh连接失败,使用kubectl describe pod命令查看改命令发现有容器返回值为137,一般是系统环境原因,且一般为内存不足导致的 ...

  9. js便签笔记(8)——js加载XML字符串或文件

    1. 加载XML文件 方法1:ajax方式.代码如下: var xhr = window.XMLHttpRequest ? new XMLHttpRequest() : new ActiveXObje ...

  10. 牛X的规则引擎urule2

    牛X的规则引擎urule2 教程:http://wiki.bsdn.org/pages/viewpage.action?pageId=75071499