2.绝版线程池
设计思路:运用队列queue

a.队列里面放任务

b.线程一次次去取任务,线程一空闲就去取任务

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, args, callback = event
try:
result = func(*args)
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
count = len(self.generate_list)
while count:
self.q.put(StopEvent)
count -= 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(3)
print(len(pool.generate_list), len(pool.free_list))
print(len(pool.generate_list), len(pool.free_list))
pool.close()
# pool.terminate()

python 绝版线程池的更多相关文章

  1. Python的线程池实现

    # -*- coding: utf-8 -*- #Python的线程池实现 import Queue import threading import sys import time import ur ...

  2. Python之路【第八篇】python实现线程池

    线程池概念 什么是线程池?诸如web服务器.数据库服务器.文件服务器和邮件服务器等许多服务器应用都面向处理来自某些远程来源的大量短小的任务.构建服务器应用程序的一个过于简单的模型是:每当一个请求到达就 ...

  3. Python之线程池

    版本一: #!/usr/bin/env python # -*- coding:utf-8 -*- import Queue import threading class ThreadPool(obj ...

  4. python自定义线程池

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

  5. Python的线程池

    #!/usr/bin/env python # -*- coding: utf-8 -*- """ concurrent 用于线程池和进程池编程而且更加容易,在Pytho ...

  6. [python] ThreadPoolExecutor线程池 python 线程池

    初识 Python中已经有了threading模块,为什么还需要线程池呢,线程池又是什么东西呢?在介绍线程同步的信号量机制的时候,举得例子是爬虫的例子,需要控制同时爬取的线程数,例子中创建了20个线程 ...

  7. 《Python》线程池、携程

    一.线程池(concurrent.futures模块) #1 介绍 concurrent.futures模块提供了高度封装的异步调用接口 ThreadPoolExecutor:线程池,提供异步调用 P ...

  8. [python] ThreadPoolExecutor线程池

    初识 Python中已经有了threading模块,为什么还需要线程池呢,线程池又是什么东西呢?在介绍线程同步的信号量机制的时候,举得例子是爬虫的例子,需要控制同时爬取的线程数,例子中创建了20个线程 ...

  9. python实现线程池

    线程池 简单线程池 import queue import threading import time class ThreadPool(object): #创建线程池类 def __init__(s ...

随机推荐

  1. FPGA软件使用基础之ISE下载配置 XILINX 下载器使用

    重新编辑 转载于https://www.cnblogs.com/lpp2jwz/p/7306020.html 下载程序 下载BIT 格式程序到FPGA 先插好下载器 在 ISE 中编译完 BIT 文件 ...

  2. 【译】第42节---EF6-DbSet.AddRange & DbSet.RemoveRange

    原文:http://www.entityframeworktutorial.net/entityframework6/addrange-removerange.aspx EF 6中的DbSet引入了新 ...

  3. HTML+CSS+JS 传智 详细笔记

    HTML(1)- -毕向东老师对Html的简介 CSS- -毕老师对CSS的简介 Javascript- -毕老师对JS的简介 html&css等等练习表(W3Cscholl) js练习表回顾 ...

  4. React Native的键盘遮挡问题(input/webview里)

    2017-06-15 1:使用keyVoaidView来解决 注意要设置behavio=“absolute”,哎.记性差 好像拼错了 2:使用下面的代码,监听键盘,然后将webView拉高就可以了 i ...

  5. _event_worldstate

    EventId 事件ID ID WorldStateUI.dbc第10列数字部分 StartValue 起始值 Entry 更新世界状态需要击杀生物或摧毁物体的entry,正数为生物,负数为物体 St ...

  6. IntelliJ IDEA Tomcat中端口被占用的问题

    早上来公司,新建了一个项目,启动Tomcat,报错,如图所示 端口1099被占用 cmd——netstat -aon|findstr 1099 此时出现了一个问题,输入:netstat -an,提示: ...

  7. Jtest的简单使用

    Jtest主要用于快速测试自己的代码是否正确 条件,导入相应的Jtest包 @Test    public void test() {        System.out.println(" ...

  8. Qt532,鼠标键盘事件_ZC

    1.判断鼠标左键是否是 按下的状态 void TdrWebview::mouseMoveEvent(QMouseEvent *_pEvent) { if (_pEvent->buttons() ...

  9. SQL中 根据行号设置每行数据的排序数值

    根据行号自动把当前行号插入到某列中 实现排序 update tempTable set DisplayOrder = right( CAST(rownum as NVARCHAR),5) from(  ...

  10. Qt5获取本机网络信息

    获取本机网络信息 在pro文件中加入如下代码 QT += network widget.h中的代码如下 #ifndef WIDGET_H #define WIDGET_H #include <Q ...