day38
一、如何开启线程
进程是操作系统调度的最小单位,线程是cpu调度的最小单位。一个进程最少有一个主线程,一个进程中能开启多个线程。真正干活的是线程。
from multiprocessing import Process from threading import Thread def task(): print("我是子线程") if __name__ == '__main__': t = Thread(target=task, args=()) t.start() print("主线程")
二、GIL全局解释锁
Python在设计之初就考虑到要在主循环中,同时只有一个线程在执行。
Python解释器中可以“运行”多个线程,但在任意时刻只有一个线程在解释器中运行。
1、GIL锁它是在python解释器中的,只在cpython中有,pypy解释器是没有GIL锁的。
2、起一个垃圾回收线程,一个是正常执行的线程。
3、设置了一把锁(GIL锁),一个线程要执行,必须拿到这把锁
4、同一时刻,开启一个进程,一个进程中可以有多个线程,只能有一个线程在执行。
5、如果是计算密集型:要开进程(计算密集型是调用CPU的计算功能,相当于开多核,开多个进程能达到效果)
6、如果是io密集型:要开线程(IO密集型不涉及到计算,开线程也能达到要求,但相当于开线程,开进城占用的资源多,且起进程消耗也大于于开线程,速度也慢于开线程)
三、进程与线程的效率比较
import time def task(): time.sleep(1) print("我是主进程") from multiprocessing import Process if __name__ == '__main__': ctime = time.time() p = Process(target=task) p.start() p.join() print("主进程") print(time.time() - ctime) import time def task(): time.sleep(1) print("我是主线程") from threading import Thread if __name__ == '__main__': ctime = time.time() p = Thread(target=task) p.start() p.join() print("主线程") print(time.time() - ctime)
四、线程之间的数据共享问题
from threading import Thread # 线程之间的数据是共享的 def work(): global n n=0 if __name__ == '__main__': n=1 t=Thread(target=work) t.start() t.join() print('主',n) # 查看结果为0,因为同一进程内的线程之间共享进程内的数据
五、Thread类的方法
1、Thread实例对象的方法:
is_alive():返回线程是否活动的。getName():返回线程名。setName():设置线程名。
threading模块提供的一些方法:
threading.currentThread():返回当前的线程变量。threading.enumerate():返回一个包含正在运行的线程的list。正在运行指线程启动后、结束前,不包括启动前和终止后的线程。threading.activeCount():返回正在运行的线程数量,与len(threading.enumerate())有相同的结果。
2、join方法
t.join():主线程等待t子线程终止,而不能join住run开启的进程
六、守护线程
主线程运行结束,整个进程结束(不管子进程是否结束,都会结束进程)。
from threading import Thread import time def task(): time.sleep(1) print("我是子线程") if __name__ == '__main__': t = Thread(target=task,) t.setDaemon(True) # 开启守护线程, 主线程结束,子线程跟着结束 t.start() print("主线程")
七、互斥锁(同步锁)
from threading import Thread, Lock import time def task(lock): # 上锁 lock.acquire() global n temp = n # 并发安全 # 10个线程都卡在这了 time.sleep(1) # n -= 1 # n=n-1 n = temp-1 # 释放锁 lock.release() if __name__ == '__main__': n = 10 ll = [] lock = Lock() for i in range(10): t = Thread(target=task, args=(lock, )) t.start() ll.append(t) for j in ll: j.join() print("主线程:", n)
八、信号量
from threading import Thread,Semaphore import time def task(i, sm): # 上锁 sm.acquire() print("%s:这个人开始上厕所了" % i) time.sleep(3) print("%s:这个人上完了" % i) # 释放锁 sm.release() # Semaphore:信号量可以理解为多把锁,同时允许多个线程来更改数据 if __name__ == '__main__': sm = Semaphore(2) # for i in range(10): t = Thread(target=task, args=(i, sm)) t.start()
九、Event事件
from threading import Thread, Event import time def girl(event): print("都女士正在恋爱中...") time.sleep(3) print("都女生分手了") # 发出分手的信号 event.set() def boy(i, event): print("渣男:%s正在等待都女生分手" % i) # 卡住 event.wait() print("渣男:%s开始追了" % i) if __name__ == '__main__': event = Event() t = Thread(target=girl, args=(event,)) t.start() for i in range(10): b_t = Thread(target=boy, args=(i, event)) b_t.start()

浙公网安备 33010602011771号