### 9.3 线程(开销小) - 线程是进程中的一部分,每一个进程至少有一个线程 - 进程是计算机最小的资源分配单位(进程是负责圈资源) - 线程是计算机中能被CPU调度最小单位(线程是负责执行具体代码) - 比较: - 进程:数据隔离 开销大 是一个资源分配单位 - 线程:数据共享 开销小 是进程的一部分 #### 9.3.1 GIL 全局解释器锁 GIL锁: - 保证了整个python程序中,只有一个线程被CPU执行 - 原因:cpython解释器中的特殊垃圾回收机制 - GIL锁导致了线程不能并行,可以并发 但是使用线程并不会影响高IO型的操作,只会对高计算型的成语有效率上的影响 #### 9.3.2 Thread模块 multiprocessing是完全房展threading的类写的,使用方法基本一样 ```python #单个子线程 from threading import Thread def func(): print('liujia') Thread(target=func).start() ``` ```python #多个子线程 import os import time from threading import Thread def func(i): print('start son thread',i) time.sleep(0.2) print('end',os.getpid()) for i in range(10): Thread(target=func,args=(i,)).start() print('main') ``` ```python #join方法 阻塞 知道子进程执行结束 def func(i): print('start son thread',i) time.sleep(0.2) print('end',os.getpid()) t_l = [] for i in range(10): t = Thread(target=func,args=(i,)) t.start() t_l.append(t) for t in t_l:t.join() print('子线程执行完毕') ``` ```python #面向对象启动线程 class MyThread(Thread): def __init__(self,i): self.i = i super().__init__() def run(self): print('start',self.i,self.ident) time.sleep(1) print('end',self.i) for i in range(10): t = MyThread(i) t.start() print(t.ident) ``` ```python #线程里的一些其他方法 from threading import current_thread,enumerate,active_count def func(i): t = current_thread() print('start son thread',i,t.ident) time.sleep(1) print('end son thread',i,os.getpid()) t = Thread(target=func,args=(1,)) t.start() print(t.ident) print(current_thread().ident) # 水性杨花 在哪一个线程里,current_thread()得到的就是这个当前线程的信息 print(enumerate()) print(active_count()) # =====len(enumerate()) ``` 注意: - 守护线程一直等到所有非守护线程结束才会结束 - 除了守护了主线程的代码之外也会守护子线程