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. Entity Framework Core

    Entity Framework是一种支持 .NET 开发人员使用 .NET 对象处理数据库的对象关系映射程序 (O/RM). 它不要求提供开发人员通常需要编写的大部分数据访问代码. Entity F ...

  2. 【转载】谈谈自己对REST、SOA、SOAP、RPC、ICE、ESB、BPM知识汇总及理解

    转载自:https://blog.csdn.net/tantexian/article/details/48196453 SOA: 维基百科解释:SOA:面向服务的软件架构(Service Orien ...

  3. 关于jQ的Ajax操作

    jQ的Ajax操作 什么是AJAX AJAX = 异步的javascript和XML(Asynchronous Javascript and XML) 它不是一门编程语言,而是利用JavaScript ...

  4. 【译】第38节---EF6-基于代码的配置

    原文:http://www.entityframeworktutorial.net/entityframework6/code-based-configuration.aspx EF6引入了基于代码的 ...

  5. js code

    //在页面增加一个放置图标的区块 if(!document.getElementById('_span_jiucuo')) document.write("<span id='_spa ...

  6. 设计模式(七)Adapter Pattern适配器模式

    适用场景:旧系统的改造升级 实际场景:java.io.InputStreamReader(InputStream)等 1.一个被适配的类 package com.littlepage.AdapterP ...

  7. L1-044. 稳赢

    这种题不是考思维,就是考你细心程度还有基础知识的,代码如下: #include <iostream> #include <string> using namespace std ...

  8. php CLI SAPI 内置Web Server

    PHP 5.4.0起, CLI SAPI 提供了一个内置的Web服务器. 这个内置的Web服务器主要用于本地开发使用,不可用于线上产品环境. URI请求会被发送到PHP所在的的工作目录(Working ...

  9. 由table理解display:table-cell

    转载自:https://segmentfault.com/a/1190000007007885 table标签(display:table) 1) table可设置宽高.margin.border.p ...

  10. leecode第四题(寻找两个有序数组的中位数)

    题解: class Solution { public: double findMedianSortedArrays(vector<int>& nums1, vector<i ...