首页 > 其他分享 >【8.0】死锁和递归锁

【8.0】死锁和递归锁

时间:2024-01-23 14:33:31浏览次数:20  
标签:8.0 metexA Thread 递归 self 死锁 抢到 线程 name

【一】死锁

【1】介绍

  • 死锁是指两个或多个进程,在执行过程中,因争夺资源而造成了互相等待的一种现象。

  • 即两个或多个进程持有各自的锁并试图获取对方持有的锁,从而导致被阻塞,不能向前执行,最终形成僵局。

  • 在这种情况下,系统资源利用率极低,系统处于一种死循环状态。

【2】示例

from threading import Thread, Lock
import time

metexA = Lock()
metexB = Lock()


# 类只要加括号多次 产生的肯定不同的对象
# 如果你想要实现多次加括号等到的是相同的对象 - 单例模式

class MyThread(Thread):
    def run(self):
        self.func1()
        self.func2()

    def func1(self):
        metexA.acquire()
        # self.name:获取当前线程名
        print(f'{self.name} 抢到了A锁')
        metexB.acquire()
        print(f'{self.name} 抢到了B锁')
        metexB.release()
        metexA.release()

    def func2(self):
        metexB.acquire()
        # self.name:获取当前线程名
        print(f'{self.name} 抢到了A锁')
        time.sleep(2)
        metexA.acquire()
        print(f'{self.name} 抢到了B锁')
        metexA.release()
        metexB.release()


def main():
    for i in range(10):
        t = MyThread()
        t.start()


if __name__ == '__main__':
    main()
    
    # Thread-1 抢到了A锁
    # Thread-1 抢到了B锁
    # Thread-1 抢到了A锁
    # Thread-2 抢到了A锁
    # 线程卡死
    # 开启十个线程 第一个线程走完第一圈 回到原地抢 A 结果第二个线程已经拿到了A 导致AB卡死

【二】递归锁

【1】介绍

  • 递归锁(也叫可重入锁)是一种特殊的锁,它允许一个线程多次请求同一个锁,称为“递归地”请求锁

  • 在该线程释放锁之前,会对锁计数器进行累加操作,线程每成功获得一次锁时,都要进行相应的解锁操作,直到锁计数器清零才能完全释放该锁。

  • 递归锁能够保证同一线程在持有锁时能够再次获取该锁,而不被自己所持有的锁所阻塞,从而避免死锁的发生。

  • 但是注意要正常使用递归锁,避免过多地获取锁导致性能下降。

【2】示例

  • 可以被连续的 acquire 和 release
  • 但是只能被第一个抢到这把锁上执行上述操作
  • 他的内部有一个计数器,每acquire一次计数 +1 每release一次 计数-1
  • 只要计数不为0,那么其他人都无法抢到该锁
from threading import Thread, Lock, RLock
import time

# 两个变量同时指向一把锁
metexA = metexB = RLock()


# 类只要加括号多次 产生的肯定不同的对象
# 如果你想要实现多次加括号等到的是相同的对象 - 单例模式

class MyThread(Thread):
    def run(self):
        self.func1()
        self.func2()

    def func1(self):
        metexA.acquire()
        # self.name:获取当前线程名
        print(f'{self.name} 抢到了A锁')
        metexB.acquire()
        print(f'{self.name} 抢到了B锁')
        metexB.release()
        metexA.release()

    def func2(self):
        metexB.acquire()
        # self.name:获取当前线程名
        print(f'{self.name} 抢到了A锁')
        time.sleep(2)
        metexA.acquire()
        print(f'{self.name} 抢到了B锁')
        metexA.release()
        metexB.release()


def main():
    for i in range(10):
        t = MyThread()
        t.start()


if __name__ == '__main__':
    main()

    # Thread-1 抢到了A锁
    # Thread-1 抢到了B锁
    # Thread-1 抢到了A锁
    # Thread-1 抢到了B锁
    # Thread-2 抢到了A锁
    # Thread-2 抢到了B锁
    # Thread-2 抢到了A锁
    # Thread-2 抢到了B锁
    # Thread-4 抢到了A锁
    # Thread-4 抢到了B锁
    # Thread-4 抢到了A锁
    # 不会卡主正常进行

标签:8.0,metexA,Thread,递归,self,死锁,抢到,线程,name
From: https://www.cnblogs.com/dream-ze/p/17982398

相关文章

  • SQL构建表层次关系,递归累加数据
     构建表的上下级关系      有一个需求,表中数据没有关系,如同一个类型的,有多个出库时间。代码--构建表的上下级关系--可以对同一个产品的,有层次关系--使用ROW_NUMBER(),来构建,最上上一级为0INSERTINTOStock([no]--编号,[quantity]......
  • SQL Server 死锁处理和优化心得
       前段时间提到的"SQLServer2005死锁解决探索",死锁严重,平均每天会发生一次死锁,在解决和处理SQLserver2005死锁中查了很多资料和想了很多办法,对为何出现死锁和怎样较少死锁有了进一步认识,在这里和大家一起分享:    SQLServer锁类型    在数据库中主要存在两种......
  • MySQL 8.0 的xtrabackup备份
     xtrabackup备份语句:   fname=`date+%F_%H-%M-%S`mkdir-p/mnt/dbbak/db_$fnamextrabackup--defaults-file=/etc/my.cnf-uhyb-phd-h/var/lib/mysql-S/var/lib/mysql/mysql.sock-Hlocalhost--port=3306--backup--parallel=4--target-dir=/mnt/dbbak/db_$f......
  • mysql8.0主从不一致,重新同步从库
    背景:线上宕机,导致数据不一致,当时为了快速恢复业务,仅使用主库,现在需要恢复,因为主从数据相差比较大,所以对从库重新进行同步。1、首先重置从库的同步设置、并清除从库不一致数据1)#停止slavestopslave;#重置slave,会重置从库相关设置。resetslaveall;2)#清除已同步......
  • 遍历二叉树非递归实现
    实现1.前序遍历publicvoidpreOrderNor(TreeNoderoot){if(root==null){return;}Stack<TreeNode>stack=newStack<>();stack.push(root);while(!stack.isEmpty()){TreeNodecur......
  • 关于死锁的一些总结
    死锁的问题历来是面试中常问的问题,可是在实际工作中可能几年都遇到不了一次这种问题.不知是幸运还是不幸,新进的这家公司刚去就遇到了两个很经典的死锁问题,这里分享一下排查和解决思路死锁的发生往往离不开多线程并发,我所遇到的两个场景分别是数据库的并发和代码层面的并......
  • Java连接8.0版本以上的数据库
    一.连接数据库在使用Java连接8.0版本以上的数据库时,可以按照如下步骤:下载需要的包,本次教程中使用的是下面这个版本。该驱动网上有许多资源,可根据自己的需求下载。建立与数据库的连接单元在合适的包下新建"DButil.java"文件并输入如下代码:importjava.sql.Connecti......
  • 在Java中连接8.0版本以上的Mysql数据库
    一.连接数据库在使用Java连接8.0版本以上的数据库时,可以按照如下步骤:下载需要的包,本次教程中使用的是下面这个版本。该驱动网上有许多资源,可根据自己的需求下载。建立与数据库的连接单元在合适的包下新建"DButil.java"文件并输入如下代码:importjava.sql.Connecti......
  • 详解匿名函数递归:从此能看懂天书代码
    最近在读《左耳听风》,里面提到了一个匿名函数递归的例子,觉得很有趣,但是我觉得书里讲解的还是有点难懂,所以尝试用自己的理解把这个问题重新讲了一遍。注:本文中所用的代码示例会同时使用JavaScript,Python语言。让我们先来看下面这段代码://javascript(f=>f(f))(f=>n=>n==......
  • mysql8.0索引数据结构
    1、为什么使用索引假如给数据使用二叉树这样的数据结构进行存储,如下图所示2、索引及其优缺点2.1、索引概述2.2、优点(1)类似大学图书馆建书目索引,提高数据检索的效率,降低数据库的IO成本,这也是创建索引最主要的原因。(2)通过创建唯一索引,可以保证数据库表中每一行数据的唯一性......