释放双眼,带上耳机,听听看~!
1.线程池-submit
python3.2版本之后才有的;
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22 1from concurrent.futures import ThreadPoolExecutor
2
3def job(num):
4 # 需要执行的任务
5 print("这是一个%s任务" %(num))
6 return "执行结果:%s" %(num)
7if __name__ == '__main__':
8 # 1. 实例化线城池对象,线城池里面包含5个线程执行任务;
9 pool = ThreadPoolExecutor(max_workers=5)
10 futures = []
11 for i in range(1000):
12 # 2.往线程池里面扔需要执行的任务, 返回的是一个对象(_base.Future()),jop函数名,i 函数job里的参数
13 f1 = pool.submit(job, i)
14 futures.append(f1)
15
16 # 3.判断第一个任务是否执行结束;
17 futures[0].done()
18
19 # 获取任务的执行结果;
20 print(futures[0].result())
21
22
线程池里面的线程越多越好吗?不是的
我们以之前爬虫ip城市的例子为例
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
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77 1import time
2def timeit(f):
3 def wrapper(*args, **kwargs):
4 start_time = time.time()
5 res = f(*args, **kwargs)
6 end_time = time.time()
7 print("%s函数运行时间:%.2f" % (f.__name__, end_time - start_time))
8 return res
9
10 return wrapper
11
12
13# python3.2版本之后才有的;
14import threading
15from concurrent.futures import ThreadPoolExecutor, wait
16from urllib.request import urlopen
17
18
19def get_area(ip):
20 url = "http://ip-api.com/json/%s" % (ip)
21 urlObj = urlopen(url)
22
23 # 服务端返回的页面信息, 此处为字符串类型
24 pageContent = urlObj.read().decode('utf-8')
25
26 # 2. 处理Json数据
27 import json
28 # 解码: 将json数据格式解码为python可以识别的对象;
29 dict_data = json.loads(pageContent)
30
31 print("""
32 %s
33 所在城市: %s
34 所在国家: %s
35
36 """ % (ip, dict_data['city'], dict_data['country']))
37
38
39# 线程池里10个任务
40@timeit
41def use_ten_thread():
42 # 1. 实例化线城池对象,线城池里面包含10个线程执行任务;
43 pool = ThreadPoolExecutor(max_workers=10)
44
45 futures = []
46 for i in range(30):
47 print("当前线程数:", threading.activeCount())
48 ip = '12.13.14.%s' %(i+1)
49 # 往线程池里面扔需要执行的任务, 返回的是一个对象(_base.Future()),
50 f1 = pool.submit(get_area, ip)
51 futures.append(f1)
52
53 # 等待futures里面所有的子线程执行结束, 再执行主线程(join())
54 wait(futures)
55
56
57# 线城池里100个任务
58@timeit
59def use_hundred_thread():
60 # 1. 实例化线城池对象,线城池里面包含100个线程执行任务;
61 pool = ThreadPoolExecutor(max_workers=100)
62
63 futures = []
64 for i in range(30):
65 print("当前线程数:", threading.activeCount())
66 ip = '12.13.14.%s' %(i+1)
67 # 往线程池里面扔需要执行的任务, 返回的是一个对象(_base.Future()),
68 f1 = pool.submit(get_area, ip)
69 futures.append(f1)
70
71 wait(futures)
72
73if __name__ == '__main__':
74 use_ten_thread()
75 use_hundred_thread()
76
77
2.线程池-map
map可以直接传值一个列表
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
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77 1import time
2
3
4def timeit(f):
5 def wrapper(*args, **kwargs):
6 start_time = time.time()
7 res = f(*args, **kwargs)
8 end_time = time.time()
9 print("%s函数运行时间:%.2f" % (f.__name__, end_time - start_time))
10 return res
11
12 return wrapper
13
14
15# python3.2版本之后才有的;
16import threading
17from concurrent.futures import ThreadPoolExecutor, wait
18from urllib.request import urlopen
19
20
21def get_area(ip):
22 url = "http://ip-api.com/json/%s" % (ip)
23 urlObj = urlopen(url)
24
25 # 服务端返回的页面信息, 此处为字符串类型
26 pageContent = urlObj.read().decode('utf-8')
27
28 # 2. 处理Json数据
29 import json
30 # 解码: 将json数据格式解码为python可以识别的对象;
31 dict_data = json.loads(pageContent)
32
33 print("""
34 %s
35 所在城市: %s
36 所在国家: %s
37
38 """ % (ip, dict_data['city'], dict_data['country']))
39
40
41@timeit
42def use_ten_thread():
43 # 1. 实例化线城池对象,线城池里面包含10个线程执行任务;
44 pool = ThreadPoolExecutor(max_workers=10)
45
46 # futures = []
47 # for i in range(30):
48 # print("当前线程数:", threading.activeCount())
49 # ip = '12.13.14.%s' %(i+1)
50 # # 往线程池里面扔需要执行的任务, 返回的是一个对象(_base.Future()),
51 # f1 = pool.submit(get_area, ip)
52 # futures.append(f1)
53 #
54 # # 等待futures里面所有的子线程执行结束, 再执行主线程(join())
55 # wait(futures)
56
57 # submit之前写的map用一句就可以
58 ips = ['12.13.14.%s' % (ip + 1) for ip in range(30)]
59 # map直接接收一个列表
60 pool.map(get_area, ips)
61
62
63@timeit
64def use_hundred_thread():
65 # 1. 实例化线城池对象,线城池里面包含100个线程执行任务;
66 pool = ThreadPoolExecutor(max_workers=100)
67 ips = ['12.13.14.%s' % (ip + 1) for ip in range(30)]
68 pool.map(get_area, ips)
69
70
71
72if __name__ == '__main__':
73 use_ten_thread()
74 use_hundred_thread()
75
76
77
线程池里10个线程时:用时129s
线程池里100个任务时,最多执行30,因为循环只有30次,运行时间128s,与10个任务时几乎相同。