• python并发编程之线程(创建线程,锁(死锁现象,递归锁),GIL锁)


    什么是线程

    进程:资源分配单位

    线程:cpu执行单位(实体),每一个py文件中就是一个进程,一个进程中至少有一个线程

    线程的两种创建方式:

    from threading import Thread
    def f1(n):
        print(n,'号线程')
    
    if __name__ == '__main__':
        t1 = Thread(target=f1,args=(1,))
        t1.start()
        print('主线程'

    from threading import Thread
    class MyThread(Thread):
        def __init__(self,name):
            super().__init__()
            self.name = name
    
        def run(self):
            print('hello:' + self.name)
    
    if __name__ == '__main__':
    
        t = MyThread('haha')
        t.start()
        print('主线程结束')

     

    线程的创建和销毁,相对于进程来说开销特别小

    线程之间资源共享,共享的是同一个进程中的资源,  资源共享就涉及到数据安全问题,加锁来解决

     

    线程锁

    From threading import Thread,Lock

    def f1: 

      Loc.acquire()

      代码

      Loc.release()

    main

      Loc = Lock()

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

    from multiprocessing import Queue
    import queue
    import time
    from threading import Lock,Thread
    
    num = 100
    def f1(loc):
        loc.acquire()
        global num
        tmp = num
        tmp -= 1
        time.sleep(0.001)
        num = tmp
        loc.release()
    
    if __name__ == '__main__':
    
        t_loc = Lock()
        t_list = []
        for i in range(10):
            t = Thread(target=f1,args=(t_loc,))
            t.start()
            t_list.append(t)
        [tt.join() for tt in t_list]
        print('主线的num',num)

    锁:牺牲了效率,保证了数据安

    死锁现象(天长地久,永不分离):

    出现在锁嵌套的时候,双方互相抢对方已经拿到的锁,导致双方互相等待,这就是死锁现象

    import time
    from threading import Thread,Lock,RLock
    
    def f1(locA,locB):
        locA.acquire()
        print('f1>>1号抢到了A锁')
        time.sleep(1)
        locB.acquire()
        print('f1>>1号抢到了B锁')
        locB.release()
    
        locA.release()
    def f2(locA,locB):
        locB.acquire()
    
        print('f2>>2号抢到了B锁')
    
        locA.acquire()
        time.sleep(1)
        print('f2>>2号抢到了A锁')
        locA.release()
    
        locB.release()
    if __name__ == '__main__':
        locA = Lock()
        locB = Lock()
        t1 = Thread(target=f1,args=(locA,locB))
        t2 = Thread(target=f2,args=(locA,locB))
        t1.start()
        t2.start()

    递归锁:

    解决死锁现象

    Rlock  首先本身就是个互斥锁,维护了一个计数器,每次acquire就+1,release就-1,当计数器为0的时候,大家才能抢这个锁

     

    import time
    from threading import Thread, Lock, RLock
    
    def f1(locA, locB):
        locA.acquire()
        print('f1>>1号抢到了A锁')
        time.sleep(1)
        locB.acquire()
        print('f1>>1号抢到了B锁')
        locB.release()
        locA.release()
    
    def f2(locA, locB):
        locB.acquire()
        print('f2>>2号抢到了B锁')
        locA.acquire()
        time.sleep(1)
        print('f2>>2号抢到了A锁')
        locA.release()
        locB.release()
    
    if __name__ == '__main__':
    
        locA = locB = RLock()  
        t1 = Thread(target=f1, args=(locA, locB))
        t2 = Thread(target=f2, args=(locA, locB))
        t1.start()
        t2.start()

     

    守护线程:

    守护线程:等待所有非守护线程的结束才结束

    守护进程:主进程代码运行结束,守护进程就随之结束

     

    import time
    from threading import Thread
    from multiprocessing import Process
    
    def f1():
        time.sleep(2)
        print('1号线程')
    def f2():
        time.sleep(3)
        print('2号线程')
    
    if __name__ == '__main__':
        t1 = Thread(target=f1,)
        t2 = Thread(target=f2,)
        t2.daemon = True
        t1.start()
        t2.start()
        print('主线程结束')

    GIL锁 :

      cpython解释器上的一把互斥锁,当线程需要进入cpu做运算时必须一个一个经过GIL锁

     

    线程的事件,信号量 与进程的事件,信号量 用法相同.

  • 相关阅读:
    那些容易忽略的事4-(正则表达式反向引用 )
    那些容易忽略的事3-(变量提升和函数提升)
    那些容易忽略的事(2)
    那些容易忽略的事(1) -变量与运算符+
    call()与apply()传参需要注意的一点
    CSS凹型导航按钮
    动态的99乘法表
    js中的for-of循环遍历数组
    交换2个变量的值
    gl.disableVertexArray P77 关闭location指定的attribute变量
  • 原文地址:https://www.cnblogs.com/fu-1111/p/10267714.html
Copyright © 2020-2023  润新知