并发编程
让程序有多个执行线索(有多个部分能够齐头并进的执行)
- 多线程 —> I/O密集型任务 —> CPython —> GIL —> 无法使用多核特性
- 多进程 —> 计算密集型任务 —> 使用到多个CPU和多核特性 —> 每个CPU高负荷运转
- 异步编程
进程
我们运行的程序通常会对应到一个或多个进程,进程是操作系统分配内存的基本单位。
线程
一个进程通常会包含一个或多个线程,线程是操作系统分配CPU的基本单位。
-
单线程程序 —> 我们的程序中只有一个执行线索(主线程)—> 创建多个线程(有多个可以并发的部分)
-
在编写多线程程序时,一定要注意线程的创建和释放有较大的开销,而且如果创建了太多的线程
-
线程之间的调度切换本身也是有开销的,所以线程并不是越多越好,最好的用法是创建若干个线程,然后重复的使用它们
线程池
-
先用一个容器,提前创建好若干个线程放进去,用线程的时候从线程池中借出一个线程
-
用完了之后,不要释放线程,而是把这个线程放回池子,让线程可以被重复利用。
-
池化技术基本上都是空间换时间的做法。
with ThreadPoolExecutor(max_workers) as pool:
pool.submit(fn, args)