1. 程式人生 > >執行緒的建立和各種鎖

執行緒的建立和各種鎖

執行緒的兩種建立方式:(重點)

  一方式

    From threading import Thread

      Def f1(n):

        Print(n)

    main:

      T = Thread(target=f1,args=(1,))

      T.start()

 

  二方式

    Class MyThread(Thread):

      Def __init__(self,n):

        Super().__init__()

        Self.n = n

      Def run(self):

        Pass

    Main:        

      T = MyThread(5)

      T.start()

 

程序:資源分配單位

執行緒:cpu執行單位(實體)

多執行緒和多程序執行時間對比:

import time
from threading import Thread
from multiprocessing import Process

def f1():
    a = 100
    b = a**2

if __name__ == '__main__':
    t_time = time.time()
    t_lis = []
    for i in range(10):
        t = Thread(target=f1,)
        t.start()
        t_lis.append(t)
    [i.join()  for i in t_lis]

    t__time = time.time()
    t___time =  t__time - t_time

    p_time = time.time()
    p_lis = []
    for i in range(10):
        p = Process(target=f1, )
        p.start()
        p_lis.append(p)

    [i.join() for i in p_lis]

    p__time = time.time()
    p___time =   p__time - p_time

    print("多執行緒時間:", t___time)
    print("多程序時間:", p___time)

  

 

鎖:犧牲了效率,保證了資料安全(重點)

  執行緒的建立和銷燬的開銷特別小

  執行緒之間資源共享,共享的是同一個程序中的資源

  資源共享就涉及到資料安全問題,加鎖來解決

  from threading import Thread,Lock

     loc = Lock()

  t = thread(target=f1,args=(loc,))

  鎖: ( 或者用with )

    loc.acquire()

    程式碼

    loc.release()

import time
from threading import Thread,Lock

num = 10
def f1(n):
    global num
    with n :
        tmg = num
        tmg -= 1
        time.sleep(0.001)
        num = tmg
        print(f"子執行緒執行完的num的值為:{num}")

if __name__ == '__main__':
    loc = Lock()
    t_lis = []
    for i in range(10):
        t = Thread(target=f1,args=(loc,))
        t.start()
        t_lis.append(t)

    [i.join() for i in t_lis]

    print(f"num的值為:{num}")

  

 

 

死鎖現象:出現在鎖巢狀的時候,雙方互相搶對方已經拿到的鎖,導致雙方互相等待,天長地久永不分離,死鎖現象(重點)

 

def fun1(n,m):
    n.acquire()
    print(f">>>1號搶到了A鎖")
    time.sleep(0.5)
    m.acquire()
    print(f">>>1號搶到了B鎖")
    m.release()
    n.release()

def fun2(n,m):
    m.acquire()
    print(f">>>2號搶到了B鎖")
    time.sleep(0.5)
    n.acquire()
    print(f">>>2號搶到了A鎖")
    n.release()
    m.release()

if __name__ == '__main__':
    locA = Lock()
    locB = Lock()
    t1 = Thread(target=fun1,args=(locA,locB,))
    t2 = Thread(target=fun2,args=(locA, locB,))
    t1.start()
    t2.start()

  

 

遞迴鎖:解決死鎖現象(重點)

  Rlock  首先本身就是個互斥鎖,維護了一個計數器,每次acquire就+1,release就-1,當計數器為0的時候,大家才能搶這個鎖

import time
from threading import Thread,RLock

def fun1(n,m):
    n.acquire()
    print(f">>>1號搶到了A鎖")
    time.sleep(0.5)
    m.acquire()
    print(f">>>1號搶到了B鎖")
    m.release()
    n.release()

def fun2(n,m):
    m.acquire()
    print(f">>>2號搶到了B鎖")
    time.sleep(0.5)
    n.acquire()
    print(f">>>2號搶到了A鎖")
    n.release()
    m.release()

if __name__ == '__main__':
    locA = locB = RLock()

    t1 = Thread(target=fun1,args=(locA,locB,))
    t2 = Thread(target=fun2,args=(locA, locB,))
    t1.start()
    t2.start()

  

 

守護執行緒(小重點)

  守護執行緒:等待所有非守護執行緒的結束才結束

  守護程序:主程序程式碼執行結束,守護程序就隨之結束

 

 

GIL鎖(重點) : cpython直譯器上的一把互斥鎖.瞭解python怎麼執行執行緒

 

 

 

 

執行緒訊號量,事件 與 程序訊號量,事件 邏輯一樣.(瞭解內容,見前面程序的部落格)