線程和進程的關係python
1.地址空間和其餘資源:進程之間相互獨立,同一進程的各線程之間共享,某進程內的線程在其餘進程不可見多線程
2.通訊:進程間的通訊IPC,線程間能夠直接寫進程數據(如全局變量)來通訊須要加鎖保證數據一致併發
3.調度和切換:線程上下文切換比進程快不少ui
4.在多線程操做系統中,進程不是一個可執行的實體,真正去執行程序的不是進程是線程,進程就是一個線程的容器spa
線程的主要特色:操作系統
1.輕型實體線程
2.獨立調度和分派的基本單位code
3.共享進程資源blog
4.可併發執行遞歸
線程的建立
兩種方法:
from threading import Thread class MyThread(Thread): def __init__(self,n): super().__init__() self.n=n def run(self): print(self.n) if __name__ == '__main__': t=MyThread(100) t.start() 第二種: from threading import Thread def func(n): print(n) if __name__ == '__main__': t=Thread(target=func,args=(100,)) t.start()
死鎖現象及遞歸鎖:
import time from threading import Thread,Lock class MyThread(Thread): def __init__(self,lockA,lockB): super().__init__() self.lockA=lockA self.lockB=lockB pass def run(self): self.f1() self.f2() def f1(self): self.lockA.acquire() print("我拿了A鎖") self.lockB. acquire() print("我是一個很好的客戶") self.lockB.release() self.lockA.release() def f2(self): self.lockB.acquire() time.sleep(0.1) print("我拿到了B鎖") self.lockA.acquire() print("我是好人") self.lockA.release() self.lockB.release() if __name__ == '__main__': lockA=Lock() lockB=Lock() t1=MyThread(lockA,lockB) t1.start() t2=MyThread(lockA,lockB) t2.start() print("我是經理")
遞歸鎖,在Python中爲了支持在同一線程中屢次請求同一資源,python提供了可重入鎖RLock。
這個RLock內部維護着一個Lock和一個counter變量,counter記錄了acquire的次數,從而使得資源能夠被屢次require。直到一個線程全部的acquire都被release,其餘的線程才能得到資源。上面的例子若是使用RLock代替Lock,則不會發生死鎖:
守護線程:
不管是進程仍是線程,都遵循:守護xx會等待主xx運行完畢後被銷燬。須要強調的是:運行完畢並不是終止運行
1 主進程在其代碼結束後就已經算運行完畢了(守護進程在此時就被回收),而後主進程會一直等非守護的子進程都運行完畢後回收子進程的資源(不然會產生殭屍進程),纔會結束,
#2 主線程在其餘非守護線程運行完畢後纔算運行完畢(守護線程在此時就被回收)。由於主線程的結束意味着進程的結束,進程總體的資源都將被回收,而進程必須保證非守護線程都運行完畢後才能結束,由於進程執行結束是要回收資源的,全部必須確保你裏面的非守護子線程所有執行完畢。