- ? 个人网站:【海拥】【摸鱼小游戏】【神级源码资源网站】
- ? 风趣幽默的前端学习课程:?28个案例趣学前端
- ? 想寻找共同学习交流、摸鱼划水的小伙伴,请点击【摸鱼学习交流群】
- ? 免费且实用的 Python 刷题(面经大全)网站:?点击跳转到网站
毫无疑问,多线程优势的一个很好的例子是使用多线程来下载多个图像或文件。实际上,由于 I/O 的阻塞特性,这是多线程的最佳用例之一。
我们将从 https://picsum.photos/200/300 检索 10 张不同的图像,这是一个免费的 API,每次点击该链接时都会提供不同的图像。然后,我们会将这 10 个不同的图像存储在一个临时文件夹中。
并发下载
是时候编写一个快速程序来同时下载我们需要的所有图像了。我们将讨论创建和启动线程。这样做的关键是通过同时编写程序来实现潜在的性能提升:
import threadingimport urllib.requestimport timedef downloadImage(imgPath, fileName):print("Downloading Image from ", imgPath)urllib.request.urlretrieve(imgPath, fileName)print("Completed Download")def createThread(i,url):imgName = "temp/image-" + str(i) + ".jpg"downloadImage(url,imgName)def main():url = "https://picsum.photos/200/300"t = time.time()# 创建一个数组,它将存储对所有线程的引用threads = []# 创建 10 个线程,将它们附加到我们的线程数组中并启动它们for i in range(10):thread = threading.Thread(target=createThread, args=(i,url,))threads.append(thread)thread.start()# 在记录完成的总时间之前,确保阵列中的所有线程都已完成其执行for i in threads:i.join()# 计算总执行时间t1 = time.time()totalTime = t - t1print("Total Execution Time {}".format(totalTime))if __name__ == '__main__':main()import threading import urllib.request import time def downloadImage(imgPath, fileName): print("Downloading Image from ", imgPath) urllib.request.urlretrieve(imgPath, fileName) print("Completed Download") def createThread(i,url): imgName = "temp/image-" + str(i) + ".jpg" downloadImage(url,imgName) def main(): url = "https://picsum.photos/200/300" t = time.time() # 创建一个数组,它将存储对所有线程的引用 threads = [] # 创建 10 个线程,将它们附加到我们的线程数组中并启动它们 for i in range(10): thread = threading.Thread(target=createThread, args=(i,url,)) threads.append(thread) thread.start() # 在记录完成的总时间之前,确保阵列中的所有线程都已完成其执行 for i in threads: i.join() # 计算总执行时间 t1 = time.time() totalTime = t - t1 print("Total Execution Time {}".format(totalTime)) if __name__ == '__main__': main()import threading import urllib.request import time def downloadImage(imgPath, fileName): print("Downloading Image from ", imgPath) urllib.request.urlretrieve(imgPath, fileName) print("Completed Download") def createThread(i,url): imgName = "temp/image-" + str(i) + ".jpg" downloadImage(url,imgName) def main(): url = "https://picsum.photos/200/300" t = time.time() # 创建一个数组,它将存储对所有线程的引用 threads = [] # 创建 10 个线程,将它们附加到我们的线程数组中并启动它们 for i in range(10): thread = threading.Thread(target=createThread, args=(i,url,)) threads.append(thread) thread.start() # 在记录完成的总时间之前,确保阵列中的所有线程都已完成其执行 for i in threads: i.join() # 计算总执行时间 t1 = time.time() totalTime = t - t1 print("Total Execution Time {}".format(totalTime)) if __name__ == '__main__': main()
在我们新修改的程序的第一行,您应该看到我们现在正在导入线程模块。然后我们抽象我们的文件名生成,将 downloadImage 函数调用到我们自己的 createThread 函数中。
在 main 函数中,我们首先创建一个空的线程数组,然后迭代 10 次,创建一个新的线程对象,将其附加到我们的线程数组中,然后启动该线程。
最后,我们通过在线程中调用 i 来遍历我们的线程数组,并在每个线程上调用 join 方法。这确保了在所有线程完成下载图像之前,我们不会继续执行剩余的代码。
如果您在您的机器上执行此操作,您应该会看到它几乎立即开始下载 10 个不同的图像。下载完成后,它再次打印出它已成功完成,您应该会看到临时文件夹中填充了这些图像。
$ concurrentImageDownloader.pyDownloading Image from https://picsum.photos/200/300Downloading Image from https://picsum.photos/200/300Downloading Image from https://picsum.photos/200/300Downloading Image from https://picsum.photos/200/300Downloading Image from https://picsum.photos/200/300Downloading Image from https://picsum.photos/200/300Downloading Image from https://picsum.photos/200/300Downloading Image from https://picsum.photos/200/300Downloading Image from https://picsum.photos/200/300Downloading Image from https://picsum.photos/200/300Completed DownloadCompleted DownloadCompleted DownloadCompleted DownloadCompleted DownloadCompleted DownloadCompleted DownloadCompleted DownloadCompleted DownloadCompleted DownloadTotal Execution Time -1.1606624126434326$ concurrentImageDownloader.py Downloading Image from https://picsum.photos/200/300 Downloading Image from https://picsum.photos/200/300 Downloading Image from https://picsum.photos/200/300 Downloading Image from https://picsum.photos/200/300 Downloading Image from https://picsum.photos/200/300 Downloading Image from https://picsum.photos/200/300 Downloading Image from https://picsum.photos/200/300 Downloading Image from https://picsum.photos/200/300 Downloading Image from https://picsum.photos/200/300 Downloading Image from https://picsum.photos/200/300 Completed Download Completed Download Completed Download Completed Download Completed Download Completed Download Completed Download Completed Download Completed Download Completed Download Total Execution Time -1.1606624126434326$ concurrentImageDownloader.py Downloading Image from https://picsum.photos/200/300 Downloading Image from https://picsum.photos/200/300 Downloading Image from https://picsum.photos/200/300 Downloading Image from https://picsum.photos/200/300 Downloading Image from https://picsum.photos/200/300 Downloading Image from https://picsum.photos/200/300 Downloading Image from https://picsum.photos/200/300 Downloading Image from https://picsum.photos/200/300 Downloading Image from https://picsum.photos/200/300 Downloading Image from https://picsum.photos/200/300 Completed Download Completed Download Completed Download Completed Download Completed Download Completed Download Completed Download Completed Download Completed Download Completed Download Total Execution Time -1.1606624126434326