操作系统中执行的一个程序,类似微信、QQ,每个程序都是一个进程
os 模块提供了 fork()
from random import randintfrom time import time, sleepdef download_task(filename): print('开始下载%s...' % filename) time_to_download = randint(5, 10) sleep(time_to_download) print('%s下载完成! 耗费了%d秒' % (filename, time_to_download))def main(): start = time() download_task('Python从入门到住院.pdf') download_task('Peking Hot.avi') end = time() print('总共耗费了%.2f秒.' % (end - start))if __name__ == '__main__': main()
开始下载Python从入门到住院.pdf... Python从入门到住院.pdf下载完成! 耗费了10秒 开始下载Peking Hot.avi... Peking Hot.avi下载完成! 耗费了9秒 总共耗费了19.02秒.
可以看到需要先等第一个文件下载完才能下载第二个文件,效率很低
from random import randintfrom time import time, sleepfrom multiprocessing import Processdef download_task(filename): print('开始下载%s...' % filename) time_to_download = randint(5, 10) sleep(time_to_download) print('%s下载完成! 耗费了%d秒' % (filename, time_to_download))def main2(): start = time() p1 = Process(target=download_task,args=("Python从入门到住院.pdf",)) p1.start() p2 = Process(target=download_task, args=("Peking Hot.avi",)) p2.start() p1.join() p2.join() end = time() print('总共耗费了%.2f秒.' % (end - start))if __name__ == '__main__': main2()
开始下载Python从入门到住院.pdf... 开始下载Peking Hot.avi... Python从入门到住院.pdf下载完成! 耗费了6秒 Peking Hot.avi下载完成! 耗费了10秒 总共耗费了10.17秒.
两个任务同时执行,总耗时不再是两个任务的时间总和
推荐 threading 模块来实现多线程编程,它提供了更好的面向对象封装
#!/usr/bin/env python# -*- coding: utf-8 -*-"""__title__ = __Time__ = 2021/3/19 18:17 __Author__ = 小菠萝测试笔记 __Blog__ = https://www.cnblogs.com/poloyy/"""from random import randintfrom threading import Threadfrom time import time, sleepdef download_task(filename): print('开始下载%s...' % filename) time_to_download = randint(5, 10) sleep(time_to_download) print('%s下载完成! 耗费了%d秒' % (filename, time_to_download))def main3(): start = time() p1 = Thread(target=download_task,args=("Python从入门到住院.pdf",)) p1.start() p2 = Process(target=download_task, args=("Peking Hot.avi",)) p2.start() p1.join() p2.join() end = time() print('总共耗费了%.2f秒.' % (end - start))if __name__ == '__main__': main3()
开始下载Python从入门到住院.pdf... 开始下载Peking Hot.avi... Peking Hot.avi下载完成! 耗费了6秒 Python从入门到住院.pdf下载完成! 耗费了8秒 总共耗费了8.01秒.
一样执行效率高很多
#!/usr/bin/env python# -*- coding: utf-8 -*-"""__title__ = __Time__ = 2021/3/19 18:17 __Author__ = 小菠萝测试笔记 __Blog__ = https://www.cnblogs.com/poloyy/"""from random import randintfrom threading import Threadfrom time import time, sleepclass downLoadTask(Thread): def __init__(self,filename): super().__init__() self.filename = filename def run(self) -> None: print('开始下载%s...' % self.filename) time_to_download = randint(5, 10) sleep(time_to_download) print('%s下载完成! 耗费了%d秒' % (self.filename, time_to_download))def main3(): start = time() p1 = downLoadTask("Python从入门到住院.pdf") p2 = downLoadTask("Peking Hot.avi") p1.start() p2.start() p1.join() p2.join() end = time() print('总共耗费了%.2f秒.' % (end - start))if __name__ == '__main__': main3()
开始下载Python从入门到住院.pdf... 开始下载Peking Hot.avi... Peking Hot.avi下载完成! 耗费了6秒 Python从入门到住院.pdf下载完成! 耗费了9秒 总共耗费了9.00秒.
也是一样的高效运行
比较点 | start | run |
作用 | 启动线程,获取 CPU 时间片 | 运行线程指定的代码块 |
线程状态 | 可运行状态 | 运行状态 |
调用次数 | 一个线程只能调用一次 | 可以重复调用 |
运行线程 | 创建了一个子线程,线程名是自己命名的 | 在主线程中调用了一个普通函数 |
注意点 | 想用多线程,必须调用 start() |
Python 中,单线程+异步 I/O 的编程模型
要充分利用 CPU 的多核特性,应该使用多进程+协程的方式
待更新