线程池

版本一:

 1 # -*- coding:utf-8 -*-
 2 import Queue
 3 import threading
 4 
 5 
 6 class ThreadPool(object):
 7 
 8     def __init__(self, max_num=20):
 9         self.queue = Queue.Queue(max_num)
10         for i in xrange(max_num):
11             self.queue.put(threading.Thread)
12 
13     def get_thread(self):
14         return self.queue.get()
15 
16     def add_thread(self):
17         self.queue.put(threading.Thread)
18 
19 """
20 pool = ThreadPool(10)
21 
22 def func(arg, p):
23     print arg
24     import time
25     time.sleep(2)
26     p.add_thread()
27 
28 
29 for i in xrange(30):
30     thread = pool.get_thread()
31     t = thread(target=func, args=(i, pool))
32     t.start()
33 """

版本二:

  1 # -*- coding:utf-8 -*-
  2 
  3 import queue
  4 import threading
  5 import contextlib
  6 import time
  7 
  8 StopEvent = object()
  9 
 10 
 11 class ThreadPool(object):
 12 
 13     def __init__(self, max_num, max_task_num = None):
 14         if max_task_num:
 15             self.q = queue.Queue(max_task_num)
 16         else:
 17             self.q = queue.Queue()
 18         self.max_num = max_num
 19         self.cancel = False
 20         self.terminal = False
 21         self.generate_list = []
 22         self.free_list = []
 23 
 24     def run(self, func, args, callback=None):
 25         """
 26         线程池执行一个任务
 27         :param func: 任务函数
 28         :param args: 任务函数所需参数
 29         :param callback: 任务执行失败或成功后执行的回调函数,回调函数有两个参数1、任务函数执行状态;2、任务函数返回值(默认为None,即:不执行回调函数)
 30         :return: 如果线程池已经终止,则返回True否则None
 31         """
 32         if self.cancel:
 33             return
 34         if len(self.free_list) == 0 and len(self.generate_list) < self.max_num:
 35             self.generate_thread()
 36         w = (func, args, callback,)
 37         self.q.put(w)
 38 
 39     def generate_thread(self):
 40         """
 41         创建一个线程
 42         """
 43         t = threading.Thread(target=self.call)
 44         t.start()
 45 
 46     def call(self):
 47         """
 48         循环去获取任务函数并执行任务函数
 49         """
 50         current_thread = threading.currentThread()
 51         self.generate_list.append(current_thread)
 52 
 53         event = self.q.get()
 54         while event != StopEvent:
 55 
 56             func, arguments, callback = event
 57             try:
 58                 result = func(*arguments)
 59                 success = True
 60             except Exception as e:
 61                 success = False
 62                 result = None
 63 
 64             if callback is not None:
 65                 try:
 66                     callback(success, result)
 67                 except Exception as e:
 68                     pass
 69 
 70             with self.worker_state(self.free_list, current_thread):
 71                 if self.terminal:
 72                     event = StopEvent
 73                 else:
 74                     event = self.q.get()
 75         else:
 76 
 77             self.generate_list.remove(current_thread)
 78 
 79     def close(self):
 80         """
 81         执行完所有的任务后,所有线程停止
 82         """
 83         self.cancel = True
 84         full_size = len(self.generate_list)
 85         while full_size:
 86             self.q.put(StopEvent)
 87             full_size -= 1
 88 
 89     def terminate(self):
 90         """
 91         无论是否还有任务,终止线程
 92         """
 93         self.terminal = True
 94 
 95         while self.generate_list:
 96             self.q.put(StopEvent)
 97 
 98         self.q.queue.clear()
 99 
100     @contextlib.contextmanager
101     def worker_state(self, state_list, worker_thread):
102         """
103         用于记录线程中正在等待的线程数
104         """
105         state_list.append(worker_thread)
106         try:
107             yield
108         finally:
109             state_list.remove(worker_thread)
110 
111 
112 
113 # How to use
114 
115 
116 pool = ThreadPool(5)
117 
118 def callback(status, result):
119     # status, execute action status
120     # result, execute action return value
121     pass
122 
123 
124 def action(i):
125     print(i)
126 
127 for i in range(30):
128     ret = pool.run(action, (i,), callback)
129 
130 time.sleep(5)
131 print(len(pool.generate_list), len(pool.free_list))
132 print(len(pool.generate_list), len(pool.free_list))
133 # pool.close()
134 # pool.terminate()

 

posted @ 2018-08-14 22:09  _E.t  阅读(140)  评论(0编辑  收藏  举报