認識進程和線程
什么是進程
1.進程是執行中的程序
2.擁有獨立的地址空間、內存、數據棧等
3.操作系統管理進程
4.派生(fork或apswn)新進程
5.進程間通信基於IPC方式共享信息
什么是線程
1.同進程下執行,並共享相同的上下文
2.線程間的信息共享和通信更加容易
3.多線程並發執行
4.需要同步原語
並發和並行的區別
1.並發:多線程並發執行 同一個時刻只有一個線程執行 進行線程的輪詢 同步原語:解釋器主循環中,使用全局解釋器鎖GIL, 保證主循環同一時刻 只有一個控制線程在執行
2.並行:多進程並行執行 同一個時刻存在多個進程的執行
python與線程
並發原理
1.py中會開啟一個解釋器的進程,使用GIl來保證進程內單個時刻單個線程的執行
2.gil的原理:
- 設置gil
- 切換近一個線程去運行
- 執行下面操作
-
- 指定數量的字節碼指令
-
- 線程主動讓出控制權
- 把線程設置回睡眠的狀態(切換出線程)
- 解鎖Gil
- 重復上面的步驟
兩種線程管理
- _thread: 提供了基本的線程和鎖
- threading:提供了更高級別、功能更全面的線程管理
-
- 支持同步機制和守護線程
Python守護線程簡述
thread模塊不支持守護線程的概念,當主線程退出時,所有的子線程都將終止,不管它們是否仍在工作,如果你不希望發生這種行為,就要引入守護線程的概念。
threading模塊支持守護線程,其工作方式是:守護線程一般是一個等待客戶端請求服務的服務器。如果沒有客戶端請求,守護線程就是空閑的,如果把一個線程設置為守護線程,就表示這個線程是不重要的,進程退出時就不需要等待這個線程執行完成。
如果主線程准備退出時,不需要等待某些子線程執行完成,就可以為這些子線程設置守護線程標記。該標記為真時,表示該線程是不重要的,或者說該線程只是用來等待客戶端請求而不做任何其它事情。
要將一個線程設置為守護線程,需要在啟動線程之前執行如下賦值語句:thread.daemon=True。同樣,要檢查線程的守護狀態,也只需要檢查這個值即可。一個新的子線程會繼承父線程的守護標記。整個Python程序(可以解讀為:主線程)將在所有非守護線程退出之后才退出,換句話說,就是沒有存活的非守護線程時。
需求:一個進程內有n個loop方法,怎么保證並發執行
//代碼塊
loops = [2, 4] # 睡眠時間
def loop(nloop, nsec):
logging.info("start loop" + str(nloop) + " at " + time.ctime())
time.sleep(nsec)
logging.info("end loop" + str(nloop) + " at " + time.ctime())
def main():
logging.info("start all at " + time.ctime())
thread = []
nloops = range(len(loops)) # 線程得數量[0,2]
for i in nloops:
print(i)
t = threading.Thread(target=loop, args=(i, loops[i])) # target表示調用的方法(loop),arg表示方法參數,t表示一個執行現成的對象
thread.append(t)#線程對象存儲到列表里
for i in nloops:
thread[i].start()#開始執行線程
for i in nloops:
thread[i].join()#知道保證線程並發執行,即前面線程沒執行完 后面線程將會一直阻塞
logging.info("end all at " + time.ctime())
if __name__ == '__main__':
main()