python - 如何同时下载多个文件并为每个完成触发特定操作?
问题描述
我需要帮助我尝试实现的功能,不幸的是我对多线程不太满意。
我的脚本从 Internet 下载 4 个不同的文件,并为每个文件调用一个专用函数,然后全部保存。问题是我是一步一步做的,因此我必须等待每次下载完成才能继续下一个。
我知道我应该做些什么来解决这个问题,但我没有成功编写代码。
实际行为:
url_list = [Url1, Url2, Url3, Url4]
files_list = []
files_list.append(downloadFile(Url1))
handleFile(files_list[-1], type=0)
...
files_list.append(downloadFile(Url4))
handleFile(files_list[-1], type=3)
saveAll(files_list)
需要的行为:
url_list = [Url1, Url2, Url3, Url4]
files_list = []
for url in url_list:
callThread(files_list.append(downloadFile(url)), # function
handleFile(files_list[url.index], type=url.index) # trigger
#use a thread for downloading
#once file is downloaded, it triggers his associated function
#wait for all files to be treated
saveAll(files_list)
谢谢你的帮助 !
解决方案
典型的做法是将IO繁重的部分,比如通过互联网获取数据和数据处理放到同一个函数中:
import random
import threading
import time
from concurrent.futures import ThreadPoolExecutor
import requests
def fetch_and_process_file(url):
thread_name = threading.currentThread().name
print(thread_name, "fetch", url)
data = requests.get(url).text
# "process" result
time.sleep(random.random() / 4) # simulate work
print(thread_name, "process data from", url)
result = len(data) ** 2
return result
threads = 2
urls = ["https://google.com", "https://python.org", "https://pypi.org"]
executor = ThreadPoolExecutor(max_workers=threads)
with executor:
results = executor.map(fetch_and_process_file, urls)
print()
print("results:", list(results))
输出:
ThreadPoolExecutor-0_0 fetch https://google.com
ThreadPoolExecutor-0_1 fetch https://python.org
ThreadPoolExecutor-0_0 process data from https://google.com
ThreadPoolExecutor-0_0 fetch https://pypi.org
ThreadPoolExecutor-0_0 process data from https://pypi.org
ThreadPoolExecutor-0_1 process data from https://python.org
推荐阅读
- sql-server - 以整数值作为日期参数的 T-SQL 日期函数
- protocol-buffers - 多个原型中的 FileOptions 扩展
- ajax - 如何在 laravel 中使用 ajax 使用搜索栏?
- javascript - 简单立方体场景中的颗粒纹理
- google-apps-script - 我在 Regexp 获取表达式时遇到错误
- javascript - React - 单击第三个组件时更新多个组件的状态
- javascript - 状态变化不会在反应钩子中的另一个卸载 useEffect 中受到影响
- typescript - Bootstrap-vue 未编译:多个“X 型不可分配给 Y 型”
- c# - 如何将 MongoDB.Driver.dll、MongoDB.Bson.dll 和 MongoDB.Driver.Core.dll 放入 GAC?
- javascript - Vuex 存储更改不更新组件