线程的创建和各种锁

线程的两种创建方式:(重点)

  一方式

    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怎么运行线程

线程信号量,事件 与 进程信号量,事件 逻辑一样.(了解内容,见前面进程的博客)

猜你喜欢

转载自www.cnblogs.com/gyc-tzx/p/10256595.html