zoukankan      html  css  js  c++  java
  • python之线程了解部分

    一、死锁(了解)

    • 死锁产生的4个必要条件:
      • 互斥:一个资源同一时刻只允许一个线程进行访问
      • 占有未释放:一个线程占有资源,且没有释放资源
      • 不可抢占:一个已经占有资源的线程无法抢占到其他线程拥有的资源
      • 循环等待:两个或者两个以上的线程,本身拥有资源,不释放资源,并且同时尝试获得其他线程所持有的资源,这种资源的申请关系形成一个闭环的链条

    • 死锁的避免:关于死锁的避免,仁者见仁智者见智
      • 线程等待时(wait)给予一个默认的等待时间
      • 线程之间资源避免相互申请对方的资源,可以通过一些容器来控制并发,比如blockqueue,等等一些线 程安全的容器
      • 尽量避免线程在等待的同时申请资源
      • 死锁检测,一个线程在等待一段时间后还没有获得资源就放弃申请。对等待时间进行检测
    from threading import Thread, Lock
    import time
    
    mutexA = Lock()
    mutexB = Lock()
    
    class MyThead(Thread):
        def run(self):
            self.func1()
            self.func2()
    
        def func1(self):
            mutexA.acquire()
            print('%s 抢到A锁' % self.name)  # 获取当前线程名
            mutexB.acquire()
            print('%s 抢到B锁' % self.name)
            mutexB.release()
            mutexA.release()
    
        def func2(self):
            mutexB.acquire()
            print('%s 抢到B锁' % self.name)
            time.sleep(2)
            mutexA.acquire()
            print('%s 抢到A锁' % self.name)  # 获取当前线程名
            mutexA.release()
            mutexB.release()
    
    if __name__ == '__main__':
        for i in range(10):
            t = MyThead()
            t.start()
    

    二、递归锁(了解)

    • 递归锁的特点
      • 可以被连续的acquire和release
      • 但是只能被第一个抢到这把锁执行上述操作
      • 它的内部有一个计数器
        • acquire一次计数加一
        • realse一次计数减一
      • 只要计数不为0 那么其他人都无法抢到该锁
    """
    # 将上述的
    mutexA = Lock()
    mutexB = Lock()
    # 换成
    mutexA = mutexB = RLock()
    

    三、信号量(了解)

    • 信号量在不同的阶段可能对应不同的技术点

    • 在并发编程中信号量指的是锁!!!

    """
    如果我们将互斥锁比喻成一个厕所的话
    那么信号量就相当于多个厕所
    """
    

    Event事件(了解)

    一些进程/线程需要等待另外一些进程/线程运行完毕之后才能运行,类似于发射信号一样

    from threading import Thread, Event
    import time
    
    event = Event()  # 造了个红绿灯
    
    
    def ligit():
        print('红灯亮了')
        time.sleep(2)
        print('绿地亮了')
        # 此时告诉等待绿灯的人可以走了
        event.set()
    
    def car(name):
        print(F'{name}正在等红灯')
        event.wait()
        #执行完wait,车才能走
        print(F'绿灯了,{name}开车走了')
    
    if __name__ == '__main__':
        t = Thread(target=ligit)
        t.start()
    
        for i in range(10):
            t = Thread(target=car, args=(F'{i+1}车',))
            t.start()
    

    四、线程q(了解)

    """
    同一个进程下多个线程数据是共享的
    为什么先同一个进程下还会去使用队列呢
    因为队列是
        管道 + 锁
    所以用队列还是为了保证数据的安全
    """
    import queue
    
    # 我们现在使用的队列都是只能在本地测试使用
    
    # 1 队列q  先进先出
    # q = queue.Queue(3)
    # q.put(1)
    # q.get()
    # q.get_nowait()
    # q.get(timeout=3)
    # q.full()
    # q.empty()
    
    
    # 后进先出q
    # q = queue.LifoQueue(3)  # last in first out
    # q.put(1)
    # q.put(2)
    # q.put(3)
    # print(q.get())  # 3
    
    # 优先级q   你可以给放入队列中的数据设置进出的优先级
    q = queue.PriorityQueue(4)
    q.put((10, '111'))
    q.put((100, '222'))
    q.put((0, '333'))
    q.put((-5, '444'))
    print(q.get())  # (-5, '444')
    # put括号内放一个元祖  第一个放数字表示优先级
    # 需要注意的是 数字越小优先级越高!!!
    
  • 相关阅读:
    sudo命令 sudoers文件
    sscanf函数
    printf格式化输出
    c文件操作
    string和char*
    c去除空格 小写转大写
    主机序和网络序转换
    ulimit用法
    mysql基础(附具体操作代码)
    ES6 class
  • 原文地址:https://www.cnblogs.com/hsyw/p/13759365.html
Copyright © 2011-2022 走看看