-
Notifications
You must be signed in to change notification settings - Fork 7
Expand file tree
/
Copy paththreadpool.py
More file actions
50 lines (42 loc) · 1.9 KB
/
threadpool.py
File metadata and controls
50 lines (42 loc) · 1.9 KB
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
from concurrent import futures
import progressbar
import time
from common import setup_down_path, get_links, download_one
from logger import logger
def download_many():
'''多线程,按线程数 并发(非并行) 下载所有图片'''
down_path = setup_down_path()
links = get_links()
find_images = len(links) # 发现的总图片链接数
ignored_images = 0 # 被忽略的图片数
visited_images = 0 # 请求成功的图片数
failed_images = 0 # 请求失败的图片数
images = []
for linkno, link in enumerate(links, 1):
image = {
'path': down_path,
'linkno': linkno,
'link': link
}
images.append(image)
workers = min(64, len(links))
with futures.ThreadPoolExecutor(workers) as executor:
to_do = [executor.submit(download_one, image) for image in images]
# 获取Future的结果,futures.as_completed(to_do)的参数是Future列表,返回迭代器。只有当有Future运行结束后,才产出future
done_iter = futures.as_completed(to_do)
with progressbar.ProgressBar(max_value=len(to_do)) as bar:
for i, future in enumerate(done_iter): # future变量表示已完成的Future对象,所以后续future.result()绝不会阻塞
result = future.result()
if result.get('ignored'):
ignored_images += 1
else:
if result.get('failed'):
failed_images += 1
else:
visited_images += 1
bar.update(i)
logger.critical('Find [{}] images, ignored [{}] images, visited [{}] images, failed [{}] images'.format(find_images, ignored_images, visited_images, failed_images))
if __name__ == '__main__':
t0 = time.time()
download_many()
logger.critical('Total Cost {:.2f} seconds'.format(time.time() - t0))