本文和大家分享的主要是
python多线程中线程池相关内容,一起来看看吧,希望对大家有所帮助。
需求:假设我们现在有一个多线程项目,每有一个用户连接进来,我们的服务器就会创建一个线程。而我们的服务器最多能够承载100
个线程,再多就会崩溃。为了防止恶意用户伪装真实用户构建大量的访问来让我们的服务器崩溃,现在需要对线程数量进行限制,一共只有
100
个线程,并且当一个用户访问结束以后线程会自动归还,等待下一个用户访问。如果
100
个线程全部被占用则
101
个用户进入阻塞时间,直到某一个用户退出,线程得到释放,
101
个用户才能被通行。
不难看出上面的需求,类似我们MySQL
的连接池。既然如此,我们的
Python
也应该有一个线程池,并且这种问题非常的常见,肯定已经有现成的库以供我们使用。今天我们就来看一下
Python
标准库中
from concurrent.futures
下的
ThreadPoolExecutor
。
第一个例子
#
首先导包
from concurrent.futures import ThreadPoolExecutor
#
创建线程池
executor = ThreadPoolExecutor(10)
#
测试方法
def test_function(num1, num2):
print(num1, num2)
return num1 + num2
#
第一个参数为具体的方法,后面为方法的参数
future = executor.submit(test_function, 1, 2)# future
的
result()
方法可以获取到函数的执行结果
print(future.result())
执行结果:
1 2
3
ThreadPoolExecutor(pool_count): pool_count
代表创建线程的数量,会返回一个该线程池的执行者对象,这个对象的
submit()
方法和
map()
方法,能够使用线程池中的线程来执行我们指定的方法,并且返回一个
Future
对象。
Future
对象的
result()
方法,可以获取我们方法执行的结果。如果方法一直没有返回或执行完毕,则
result()
方法会进入阻塞状态,直到我们的方法返回或执行完毕。
使用map()
方法批量执行
from concurrent.futures import ThreadPoolExecutor
executor = ThreadPoolExecutor(10)
def test_function(num1, num2):
print(num1, num2)
return num1 + num2
"""
executor.map(function,
参数
1_list,
参数
2_list,
参数
n_list)
参数1_list:
代表方法第一个参数的列表
参数2_list:
代表方法第二个参数的列表
如:
executor.map(test_function, [1, 2], [5, 5])
代表,执行test_function
方法,第一个线程的参数为
1
和
5
,第二个线程的参数为
2
和
5
。
线程1
:
test_function(1, 5)
结果为
1 + 5 = 6
该方法返回的是一个可迭代的对象,里面直接包含了每个方法执行的结果,不需要调用result()
方法。
详情:https://docs.python.org/3/library/concurrent.futures.html
"""
result_iterators = executor.map(test_function, [1, 2], [5, 5])
for result in result_iterators:
print(result)
执行结果:
1 5
2 5
6
7
尝试一下所有线程都被占用的情况
import timefrom concurrent.futures import ThreadPoolExecutor
#
方便测试创建三个线程
executor = ThreadPoolExecutor(3)
def test_function(num1, num2):
print(num1, num2)
#
方法休眠十秒
time.sleep(10)
return num1 + num2
#
使用三个线程,占用线程池全部线程
#
由于我们的结果是十秒后返回,所以这里也会被阻塞,十秒后才会收到结果
result_iterators = executor.map(test_function, [1, 2, 3], [5, 6, 7])
for result in result_iterators:
print(result)
#
到这里很显然前面三个线程都在使用中,
10
秒后才能得到执行
future = executor.submit(test_function, 4, 8)print(future.result())
执行结果:
1 5
2 6
3 7
6
8
10
4 8
12
[Finished in 20.2s]