自定义线程池的实现思路

在使用多线程的过程中,一旦任务数量过多,如果不对派生出来的子线程做出限制的话,多线程极有可能会拉低程序的性能,这时,我们需要维护一个固定数量的线程,也就是线程池的概念

实现线程池的思路:

  • 设置线程池的容量
  • 每取走一个线程,在线程池中就减少一个线程
  • 每个子线程的任务执行完毕,把自己的线程配额放回线程池中
  • 当线程池中的线程全部分配完毕,新的任务需要等待获取线程池中的线程

基于以上的需求,我们可以通过队列来实现线程池的功能

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
import queue
import threading
import time

class ThreadPool:
# 接收的实例化参数为线程池的最大容量
def __init__(self, maxsize=5):
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)

def task(arg, pool):
"""接收了一个线程池对象"""
print(arg)
time.sleep(1)

# 执行完毕函数的主体后,将拿到的线程配额再放回到线程池中
pool.add_thread()

if __name__ == '__main__':
# 创建一个容量为5的线程池
pool = ThreadPool(5)

for i in range(59):

# 从线程池中拿到一个线程对象
# 相当于 t = threading.Thread
t = pool.get_thread()

# 创建子线程对象
# 把线程池对象传递到执行函数中
o = t(target=task, args=(i, pool,))

o.start()