example19.py 2.8 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394
  1. """
  2. 扩展性系统性能
  3. - 垂直扩展 - 增加单节点处理能力
  4. - 水平扩展 - 将单节点变成多节点(读写分离/分布式集群)
  5. 并发编程 - 加速程序执行 / 改善用户体验
  6. 耗时间的任务都尽可能独立的执行,不要阻塞代码的其他部分
  7. - 多线程
  8. 1. 创建Thread对象指定target和args属性并通过start方法启动线程
  9. 2. 继承Thread类并重写run方法来定义线程执行的任务
  10. 3. 创建线程池对象ThreadPoolExecutor并通过submit来提交要执行的任务
  11. 第3种方式可以通过Future对象的result方法在将来获得线程的执行结果
  12. 也可以通过done方法判定线程是否执行结束
  13. - 多进程
  14. - 异步I/O
  15. """
  16. import glob
  17. import os
  18. import time
  19. from concurrent.futures import ThreadPoolExecutor
  20. from threading import Thread
  21. from PIL import Image
  22. # class ThumbnailThread(Thread):
  23. # def __init__(self, infile):
  24. # self.infile = infile
  25. # super().__init__()
  26. # def run(self):
  27. # file, ext = os.path.splitext(self.infile)
  28. # filename = file[file.rfind('/') + 1:]
  29. # for size in (32, 64, 128):
  30. # outfile = f'thumbnails/{filename}_{size}_{size}.png'
  31. # image = Image.open(self.infile)
  32. # image.thumbnail((size, size))
  33. # image.save(outfile, format='PNG')
  34. def gen_thumbnail(infile):
  35. file, ext = os.path.splitext(infile)
  36. filename = file[file.rfind('/') + 1:]
  37. for size in (32, 64, 128):
  38. outfile = f'thumbnails/{filename}_{size}_{size}.png'
  39. image = Image.open(infile)
  40. image.thumbnail((size, size))
  41. image.save(outfile, format='PNG')
  42. # def main():
  43. # start = time.time()
  44. # threads = []
  45. # for infile in glob.glob('images/*'):
  46. # # t = Thread(target=gen_thumbnail, args=(infile, ))
  47. # t = ThumbnailThread(infile)
  48. # t.start()
  49. # threads.append(t)
  50. # for t in threads:
  51. # t.join()
  52. # end = time.time()
  53. # print(f'耗时: {end - start}秒')
  54. def main():
  55. pool = ThreadPoolExecutor(max_workers=30)
  56. futures = []
  57. start = time.time()
  58. for infile in glob.glob('images/*'):
  59. # submit方法是非阻塞式的方法
  60. # 即便工作线程数已经用完,submit方法也会接受提交的任务
  61. future = pool.submit(gen_thumbnail, infile)
  62. futures.append(future)
  63. for future in futures:
  64. # result方法是一个阻塞式的方法 如果线程还没有结束
  65. # 暂时取不到线程的执行结果 代码就会在此处阻塞
  66. future.result()
  67. end = time.time()
  68. print(f'耗时: {end - start}秒')
  69. # shutdown也是非阻塞式的方法 但是如果已经提交的任务还没有执行完
  70. # 线程池是不会停止工作的 shutdown之后再提交任务就不会执行而且会产生异常
  71. pool.shutdown()
  72. if __name__ == '__main__':
  73. main()