1.概念
- 线程是轻量级的进程,它的存在依赖于进程.
- 线程只被分配给运行所需最低限度的系统资源(寄存器,栈),所以同一进程内的多个线程数据是共享的.
- 线程是计算机中被CPU调度的最小单位.
2.守护线程
- 守护线程与守护进程不同,守护线程随着主进程的结束才结束.
- 主线程不负责子线程的资源回收.
- 通过obj.setDaemon(True)或设置daemon参数的方式设置为守护线程.
3.GIL锁
GIL(Global Interpreter Lock)中文名为全局解释器锁,是CPython解释器的特性
任何Python同一进程的线程在执行前,都必须先获得GIL锁,然后在执行一定时间后,解释器就自动释放GIL锁,让其他的线程也有机会执行.
虽然这样做保证了多核操作数据的数据安全问题,但是这使得在同一时间,同一进程的多个线程就只有一个线程能够使用CPU资源,多线程并不能利用多核CPU资源
结论为Python中的多线程并没有性能优势,只有在程序高IO时,才会使用多线程.
但是即使有了GIL锁,多个线程同时操作全局变量,并且此操作不是原子性操作(即不可拆分的操作)时,就会发生数据不安全的现象,在这种时候,为了数据安全我们依然要加上锁
4.线程池
由于threading出现比较早,所以threading中并没有线程池,如果需要线程池,需要concurrent.futures模块中的ThreadPoolExecutor类来实例化线程池.
submit 开启异步任务,作用与apply_async相同
传参数时不再需要args = tuple, 直接按顺序传参即可
result 返回调用返回的值
add_done_callback 回调函数,需要用result获取值
这里的回调参数是一个方法
shutdown 停止向进程池中添加任务并阻塞直到进程池执行完毕.作用与close + join相同