線程不會複製主線程的空間,而是在進程內部劃分一個區域,線程間能夠共享資源( 會影響全局變量 ),局部變量不共享php
進程裏至少有一個線程,線程不會建立新的空間;進程會複製主進程的全部文件,開闢新的內存空間,佔資源。python
進程 每增長一個進程就會建立一分內存空間 修改全局變量不會有影響 通訊麻煩c#
例:兒子一出生就和老子分家,並搬出去 ,進程間資源互不影響,進程間通訊須要使用隊列來傳遞。安全
線程 共享內存空間 修改全局變量會影響 線程安全 互斥鎖ruby
例: 兒子一出生就和老子放假了,不過是合租。客廳( 全局 )相互公用,臥室(局部)私有。多線程
# demo import time # 導入包 import threading def sing(num): print('我在唱歌:{}次'.format(num)) # 睡1秒 time.sleep(1) for i in range(10): # 建立線程 t = threading.Thread(target=sing, args=(i,)) # 開啓線程 t.start() # sing(i)
線程的全局變量,是不安全的,須要使用互斥鎖來進行鎖定狀態(似: MySQL中的事務)ui
示例:線程
import threading num = 0 def add(): # 修改全局變量 global num # 開啓互斥鎖 lock.acquire() for i in range(100000): num += 1 print(f'add:{num}') # 關閉互斥鎖 lock.release() def read(): # 修改全局變量 global num # 開啓互斥鎖 lock.acquire() for i in range(100000): num += 1 print(f'read:{num}') # 關閉互斥鎖 lock.release() # 建立一個鎖對象(只須要建立一個) lock = threading.Lock() # 建立一個線程 t = threading.Thread(target=add) # 開啓線程 t.start() # 建立一個線程 t = threading.Thread(target=read) # 開啓線程 t.start()
運行結果:調試
若是不使用互斥鎖進行鎖定,當數值較小的時候可能沒有太大的變化,若是大了,必有問題( 運算錯誤 )code
import threading class MyThread(threading.Thread): # 初始化 def __init__(self, name): # 繼承類必需要繼續初始化 super(MyThread, self).__init__() self.name = name def run(self): # run 是固定的 print(f'傳入的參數是:{self.name}') def main(): # 實例對象 myThread = MyThread('張三') # 開啓 myThread.start() if __name__ == '__main__': main()
繼承必需要初始化繼承類
繼承類方式裏面 的run方法是固定的,不可變!
互斥鎖也是在threading類上,使用方法
# 建立一個鎖對象(只須要建立一個) lock = threading.Lock()
互斥鎖:
遵循: 原子性,惟一性
通俗的講: 互斥鎖是一個狀態,當狀態( 鎖定 )開啓時,其餘的動做將不能進行操做,當解除( 解鎖 )狀態時,其餘的能夠接管繼續操做.[ 主要用於線程安全 ]
死鎖的解決方案:
解決:添加超時時間
加鎖越多,效率越慢
案例:
import threading, time def p1(): # 上鎖 while True: if lock1.acquire(): print('1') time.sleep(1) # 執行完成時將p2解鎖 lock2.release() def p2(): while True: if lock2.acquire(): print('2') time.sleep(1) # p2執行完成時解鎖p3 lock3.release() def p3(): while True: if lock3.acquire(): print('3') time.sleep(1) # p3執行完成時解鎖p1 lock1.release() # 建立線程 t1 = threading.Thread(target=p1) t2 = threading.Thread(target=p2) t3 = threading.Thread(target=p3) # 建立鎖 lock1 = threading.Lock() lock2 = threading.Lock() lock3 = threading.Lock() # 將p2鎖住 lock2.acquire() # 將p3鎖住 lock3.acquire() # 開啓線程 t1.start() t2.start() t3.start()
特定環境需求,同步下不講效率
進程:獨立內存空間 資源分配的單元
線程:共享內存空間 大大減小內存的使用 線程不安全 調試單元 最後作事情的那我的
一個程序運行至少一個進程,至少一個線程
何時使用多進程,何時時候使用多線程?
IO密集型:多線程 input output
CPU密集型:多進程
編譯型:c go c#
解釋型:python php ruby perl js
GIL: 全局解釋鎖 不是PYthon特徵 cpython( 解釋器 ) 多線程的時候,爲了保證線程自己安全,加了這個全局解釋鎖,
在同一時間點,只能有一個線程去CPU上執行
C語言