Python案例-网络编程-线程池

线程池:

python2.*没有真正的线程池,
python3.*功能不强,所以一般要么自己写,要么用第三方软件
以下举例两种自定义线程池代码

第一种:通过for循环配合队列来实现多线程
特点:
1、队列中存放线程;
2、线程使用完就关闭,然后重新创,不能被重复使用;
3、一旦开启程序,线程池就会开到最大上线;

#!/usr/bin/env python
# -- coding = 'utf-8' --
# Author Allen Lee
# Python Version 3.5.1
# OS Windows 7
import queue
import threading
import time
class ThreadPool:
    def __init__(self,maxsize):
        self.maxsize = maxsize
        self._q = queue.Queue(maxsize)
        for i in range(maxsize):
            self._q.put(threading.Thread)
    def get_thread(self):
        return self._q.get()
    def add_thread(self):
        self._q.put(threading.Thread)

pool = ThreadPool(5)

def task(arg,p):
    print(arg)
    time.sleep(1)
    p.add_thread

for i in range(100):
    #threading.Thread类
    t = pool.get_thread()
    obj = t(target=task,args=(i,pool,))
    obj.start()

第二种:稍复杂一些的
特点:
1、队列里存放任务;
2、任务分两种:a、真实任务;b、关闭信号;
3、根据当前任务量来创建线程;
4、线程可以重复使用;

#!/usr/bin/env python
# -- coding = 'utf-8' --
# Author Allen Lee
# Python Version 3.5.1
# OS Windows 7
import threading
import time
import queue
import contextlib

stoptarget = object()

#自建一个线程池类
class ThreadPool(object):
    #在构造方法中创建队列,传递队列长度参数maxsize
    def __init__(self,maxsize,maxtasklist=None):
        if maxtasklist:
            self.q = queue.Queue(maxtasklist)
        else:
            self.q = queue.Queue(maxsize)
        self.maxsize = maxsize
        #任务执行完正常退出的标签
        self.Nclose = False
        #不管是否执行完,都退出的标签
        self.Iclose = False
        #正在被使用的线程列表
        self.inuse_list = []
        #空闲线程列表
        self.free_list = []

    def run(self,task,args,callback=None):
        """
        #task 任务函数
        #args 函数参数
        #callback 不论结果的回调函数,其有两个参数:1、执行状态;2、返回值,default=None,既不执行回调函数
        #返回值,如果线程池结束,返回True or None
        """

        #如何是线程池正常执行后关闭的,退出
        if self.Nclose:
            return
        #如果没有可用线程,且在用线程小于线程池最大数量,则补充一个线程,其作用为监听当前线程池的线程数,放在执行程序里相当于守护进程
        if len(self.free_list) == 0 and len(self.inuse_list) < self.maxsize:
            self.inuse_thread()
        obj = (task,args,callback,)
        self.q.put(obj)

    #创建线程方法
    def inuse_thread(self):
        opj = threading.Thread(target=self.call)
        opj.start()

    #循环获取线程的方法
    def call(self):
        current_thread = threading.currentThread
        #在忙碌的线程列表中添加
        self.inuse_list.append(current_thread)
        #获取队列中信息
        event = self.q.get()
        #判断获取的消息是否为停止,如果不是,则获得读取消息中的task,args,callback 字段内容
        while event != stoptarget:
            task,args,callback = event
            #异常判断,如果只选task成功,在将返回值赋给result,并置success 为True
            try:
                result = task(*args)
                success = True
            #如果异常则置于False和None
            except Exception as f:
                success = False
                result = None
            #如果回调函数不为空则将success和result返回给回调函数,否则不执行回调函数
            if callback is not None:
                try:
                    callback(success, result)
                except Exception as f:
                    pass
            with self.worker_state(self.free_list, current_thread):
                #如任务异常退出,则给队列里输入stoptarget的消息
                if self.Iclose:
                    event = stoptarget
                #否则继续获取消息
                else:
                    event = self.q.get()
        else:
                #将已经执行完的线程从忙碌线程列表中去掉
                self.inuse_list.remove(current_thread)

    #执行完所有的任务后,正常关闭
    def Nclose(self):
        self.Nclose = True
        full_size = len(self.inuse_list)
        while full_size:
            self.q.put(stoptarget)
            full_size -= 1

     #无论是否还有任务,终止线程,此为异常关闭
    def Iclose(self):
        self.Iclose = True
        while self.Iclose:
            self.q.put(stoptarget)
        self.q.empty()

    #用于记录线程中正在等待的线程数,这里使用上下文模块的上下文管理方法处理之
    @contextlib.contextmanager
    def worker_state(self, state_list, worker_thread):
        state_list.append(worker_thread)
        #生成迭代器
        try:
            yield
        finally:
            state_list.remove(worker_thread)
#创建线程池为5个线程的对象
pool = ThreadPool(5)

#此为回调函数
def callback(status,result):
    print(status,result)

#此为模拟的task
def action(i):
    print(i)

#100个任务请求
for i in range(100):
    t = pool.run(action,(i,),callback)

time.sleep(2)
print(len(pool.inuse_list), len(pool.free_list))

你可能感兴趣的:(Python案例,python开发之路)