一、死锁现象与递归锁
所谓死锁: 是指两个或两个以上的进程或线程在执行过程中,因争夺资源而造成的一种互相等待的现象,若无外力作用,它们都将无法推进下去。此时称系统处于死锁状态或系统产生了死锁,这些永远在互相等待的进程称为死锁进程
解决方法,递归锁,这个RLock内部维护着一个Lock和一个counter变量,counter记录了acquire的次数,从而使得资源可以被多次require。直到一个线程所有的acquire都被release,其他的线程才能获得资源。
一个线程拿到锁,counter加1,该线程内又碰到加锁的情况,则counter继续加1,这期间所有其他线程都只能等待,等待该线程释放所有锁,即counter递减到0为止
from threading import Thread,Lock
import time
mutexA=Lock()
mutexB=Lock()
class MyThread(Thread):
    def run(self):
        self.func1()
        self.func2()
    def func1(self):
        mutexA.acquire()
        print('\033[41m%s 拿到A锁\033[0m' %self.name)
        mutexB.acquire()
        print('\033[42m%s 拿到B锁\033[0m' %self.name)
        mutexB.release()
        mutexA.release()
    def func2(self):
        mutexB.acquire()
        print('\033[43m%s 拿到B锁\033[0m' %self.name)
        time.sleep(2)
        mutexA.acquire()
        print('\033[44m%s 拿到A锁\033[0m' %self.name)
        mutexA.release()
        mutexB.release()
if __name__ == '__main__':
    for i in range(10):
        t=MyThread()
        t.start()
'''
Thread-1 拿到A锁
Thread-1 拿到B锁
Thread-1 拿到B锁
Thread-2 拿到A锁
然后就卡住,死锁了
'''
二、信号量
Semaphore管理一个内置的计数器
# from multiprocessing import Semaphore
from threading import Thread,Semaphore,current_thread
import time,random
sm=Semaphore(5)
#同时只有5个线程可以获得semaphore,即可以限制最大连接数为5
def go_wc():
    sm.acquire()
    print('%s 上厕所ing' %current_thread().getName())
    time.sleep(random.randint(1,3))
    sm.release()
if __name__ == '__main__':
    for i in range(23):
        t=Thread(target=go_wc)
        t.start()
三、线程event(全局变量Falsa or True)
a、案例一: 等待check重置event内的值后,connect从event.wait()后继续运行
from threading import Event,current_thread,Thread
import time
event=Event()   #event内部维护着一个全局变量
def check():
    print('%s 正在检测服务是否正常....' %current_thread().name)
    time.sleep(3)
    event.set() #改变event中的全局变量的值
def connect():
    print('%s 等待连接...' %current_thread().name)
    event.wait() #等待全局变量的值被重置;如果括号中为1,即只等1秒
    print('%s 开始连接...' % current_thread().name)
if __name__ == '__main__':
    t1=Thread(target=connect)
    t2=Thread(target=connect)
    t3=Thread(target=connect)
    c1=Thread(target=check)
    t1.start()
    t2.start()
    t3.start()
c1.start()
b、案例二:三次刷尝试后退出
from threading import Event,current_thread,Thread
import time
event=Event()
def check():
    print('%s 正在检测服务是否正常....' %current_thread().name)
    time.sleep(5)
    event.set()
def connect():
    count=1
    while not event.is_set():#没有被设置为True
        if count ==  4:
            print('尝试的次数过多,请稍后重试')
            return
        print('%s 尝试第%s次连接...' %(current_thread().name,count))
        event.wait(1)
        count+=1
    print('%s 开始连接...' % current_thread().name)
if __name__ == '__main__':
    t1=Thread(target=connect)
    t2=Thread(target=connect)
    t3=Thread(target=connect)
    c1=Thread(target=check)
    t1.start()
    t2.start()
    t3.start()
    c1.start()
四、线程Queue
import queue
q=queue.Queue(3) #队列:先进先出
q.put(1)
q.put(2)
q.put(3)
# q.put(4)       #阻塞
print(q.get())
print(q.get())
print(q.get())
q=queue.LifoQueue(3) #堆栈:后进先出
q.put('a')
q.put('b')
q.put('c')
print(q.get())
print(q.get())
print(q.get())
q=queue.PriorityQueue(3) #优先级队列:可以以小元组的形式往队列里存值,第一个元素代表优先级,数字越小优先级越高
q.put((10,'user1'))
q.put((-3,'user2'))
q.put((-2,'user3'))
print(q.get())
print(q.get())
print(q.get()) #(10,'user1')

(并发编程)RLock(与死锁现象),Semaphore,Even事件,线程Queue的更多相关文章

  1. Java并发编程工具类 CountDownLatch CyclicBarrier Semaphore使用Demo

    Java并发编程工具类 CountDownLatch CyclicBarrier Semaphore使用Demo CountDownLatch countDownLatch这个类使一个线程等待其他线程 ...

  2. Python并发编程04 /多线程、生产消费者模型、线程进程对比、线程的方法、线程join、守护线程、线程互斥锁

    Python并发编程04 /多线程.生产消费者模型.线程进程对比.线程的方法.线程join.守护线程.线程互斥锁 目录 Python并发编程04 /多线程.生产消费者模型.线程进程对比.线程的方法.线 ...

  3. 并发编程-线程-死锁现象-GIL全局锁-线程池

    一堆锁 死锁现象 (重点) 死锁指的是某个资源被占用后,一直得不到释放,导致其他需要这个资源的线程进入阻塞状态. 产生死锁的情况 对同一把互斥锁加了多次 一个共享资源,要访问必须同时具备多把锁,但是这 ...

  4. java并发编程如何预防死锁

    在java并发编程领域已经有技术大咖总结出了发生死锁的条件,只有四个条件都发生时才会出现死锁: 1.互斥,共享资源X和Y只能被一个线程占用 2.占有且等待,线程T1已经取得共享资源X,在等待共享资源Y ...

  5. Java并发编程实战 04死锁了怎么办?

    Java并发编程文章系列 Java并发编程实战 01并发编程的Bug源头 Java并发编程实战 02Java如何解决可见性和有序性问题 Java并发编程实战 03互斥锁 解决原子性问题 前提 在第三篇 ...

  6. Java并发编程核心方法与框架-Semaphore的使用

    Semaphore中文含义是信号.信号系统,这个类的主要作用就是限制线程并发数量.如果不限制线程并发数量,CPU资源很快就会被耗尽,每个线程执行的任务会相当缓慢,因为CPU要把时间片分配给不同的线程对 ...

  7. Java并发编程-深入Java同步器AQS原理与应用-线程锁必备知识点

    并发编程中我们常会看到AQS这个词,很多朋友都不知道是什么东东,博主经过翻阅一些资料终于了解了,直接进入主题. 简单介绍 AQS是AbstractQueuedSynchronizer类的缩写,这个不用 ...

  8. Python并发编程之消息队列补充及如何创建线程池(六)

    大家好,并发编程 进入第六篇. 在第四章,讲消息通信时,我们学到了Queue消息队列的一些基本使用.昨天我在准备如何创建线程池这一章节的时候,发现对Queue消息队列的讲解有一些遗漏的知识点,而这些知 ...

  9. 同步锁 死锁与递归锁 信号量 线程queue event事件

    二个需要注意的点: 1 线程抢的是GIL锁,GIL锁相当于执行权限,拿到执行权限后才能拿到互斥锁Lock,其他线程也可以抢到GIL,但如果发现Lock任然没有被释放则阻塞,即便是拿到执行权限GIL也要 ...

随机推荐

  1. js拼接HTML页面元素a标签遇到的问题

    业务,如下图需要做一个广告轮播的图片链接 使用了ajax请求后台,在js拼接html,关键代码: $("#scroll_img").html(""); for ...

  2. HDU - 3974 Assign the task (线段树区间修改+构建模型)

    https://cn.vjudge.net/problem/HDU-3974 题意 有一棵树,给一个结点分配任务时,其子树的所有结点都能接受到此任务.有两个操作,C x表示查询x结点此时任务编号,T ...

  3. HDU 1033(坐标移动 模拟)

    题意是说有一点从(300,410)的位置出发,向右移动到(310,410)后开始转向,A 表示向顺时针转,V 表示向逆时针转,每次转向后沿当前方向前进 10 个单位, 输出其坐标,再补充一点格式上的东 ...

  4. [Android] Android 常见第三方库汇总地址

    Android 常见第三方库汇总地址 https://github.com/wasabeef/awesome-android-libraries List of Android Libraries T ...

  5. SpringBoot系列: 与Spring Rest服务交互数据

    不管是单体应用还是微服务应用, 现在都流行Restful风格,  下图是一个比较典型的使用rest的应用架构, 该应用不仅使用database数据源, 而且用到了一个Weather微服务, 另一方面, ...

  6. Android RelativeLayout属性含义

    a).第一类:属性值为true或false android:layout_centerHrizontal 水平居中 android:layout_centerVertical 垂直居中 android ...

  7. 让WeuiPicker隐藏日期中的日,只保留年月

    weui.datePicker({ start: 1990, end: new Date().getFullYear() + 3, defaultValue: [year, month, 1], on ...

  8. string.GetHashCode获取值不一样

    今天在使用程序时发现两个String.GetHashCode值不一样,通过测试 (1)程序在两台不同的计算机上运行,没有变化. (2)修改32位,64位,值有变化,说明GetHashCode和.net ...

  9. 回顾一下C++ 编写DLL

    项目模版使用Win32工程创建的dll项目 一.原始代码 使用depends查看导出函数 二.不同编译方式区别 C方式编译(extern "C"): __stdcall调用约定:输 ...

  10. 【python小练】0020

    第 0020 题: 登陆中国联通网上营业厅 后选择「自助服务」 --> 「详单查询」,然后选择你要查询的时间段,点击「查询」按钮,查询结果页面的最下方,点击「导出」,就会生成类似于 2014年1 ...