测试开发面试题:死锁的前世今生

📝 面试求职: 「面试试题小程序」 ,内容涵盖 测试基础、Linux操作系统、MySQL数据库、Web功能测试、接口测试、APPium移动端测试、Python知识、Selenium自动化测试相关、性能测试、性能测试、计算机网络知识、Jmeter、HR面试,命中率杠杠的。(大家刷起来…)

📝 职场经验干货:

软件测试工程师简历上如何编写个人信息(一周8个面试)

软件测试工程师简历上如何编写专业技能(一周8个面试)

软件测试工程师简历上如何编写项目经验(一周8个面试)

软件测试工程师简历上如何编写个人荣誉(一周8个面试)

软件测试行情分享(这些都不了解就别贸然冲了.)

软件测试面试重点,搞清楚这些轻松拿到年薪30W+

软件测试面试刷题小程序免费使用(永久使用)


死锁的定义:

死锁是计算机科学中的一个术语,指的是在多线程或多进程系统中,两个或更多的进程无法继续执行,因为它们互相等待对方释放资源。简单来说,死锁会导致系统中的某些进程或线程陷入一种无尽的等待状态,从而无法继续执行。

死锁的产生原因

死锁通常由以下四个必要条件同时满足产生:

  1. 互斥条件:至少有一个资源是以非共享的模式被占用,即某个资源只能被一个进程使用。

  2. 保持并等待条件:一个过程在保持某资源的同时,等待其他资源。

  3. 不抢占条件:已经分配给某个进程的资源不能被强制抢占,资源只能在进程完成后自愿释放。

  4. 循环等待条件:存在一个进程等待资源的循环链,即进程 A 等待进程 B 持有的资源,进程 B 等待进程 C 的资源,依此类推,直到最后一个进程等待进程 A 持有的资源。

Python中的死锁案例

下面是一个简单的Python死锁示例,使用threading模块创建多个线程:

import threading  
import time  

# 定义两个锁  
lock1 = threading.Lock()  
lock2 = threading.Lock()  

def thread1_func():  
    with lock1:  
        print("Thread 1: Holding lock 1...")  
        time.sleep(1)  # 模拟长时间持有锁  
        print("Thread 1: Waiting for lock 2...")  
        with lock2:  
            print("Thread 1: Acquired lock 2!")  

def thread2_func():  
    with lock2:  
        print("Thread 2: Holding lock 2...")  
        time.sleep(1)  # 模拟长时间持有锁  
        print("Thread 2: Waiting for lock 1...")  
        with lock1:  
            print("Thread 2: Acquired lock 1!")  

# 创建两个线程  
t1 = threading.Thread(target=thread1_func)  
t2 = threading.Thread(target=thread2_func)  

# 启动线程  
t1.start()  
t2.start()  

# 等待线程结束  
t1.join()  
t2.join()  

print("Program finished.")

在这个例子中,thread1_func 持有 lock1,然后试图获取 lock2;而 thread2_func 持有 lock2,然后试图获取 lock1。这样就形成了一个死锁。

修改为非死锁

一种常见的解决死锁的方法是改变资源的请求顺序。下面是修改后的代码,按照顺序获取锁:

def thread1_func():  
    with lock1:  
        print("Thread 1: Holding lock 1...")  
        time.sleep(1)  # 模拟长时间持有锁  
        print("Thread 1: Waiting for lock 2...")  
        with lock2:  
            print("Thread 1: Acquired lock 2!")  

def thread2_func():  
    with lock1:  # 按照相同的顺序获取锁  
        print("Thread 2: Holding lock 1...")  
        time.sleep(1)  # 模拟长时间持有锁  
        print("Thread 2: Waiting for lock 2...")  
        with lock2:  
            print("Thread 2: Acquired lock 2!")  

# 创建两个线程  
t1 = threading.Thread(target=thread1_func)  
t2 = threading.Thread(target=thread2_func)  

# 启动线程  
t1.start()  
t2.start()  

# 等待线程结束  
t1.join()  
t2.join()  

print("Program finished.")

防止死锁的方法

  1. 锁的顺序:确保所有线程按照相同的顺序请求锁,避免出现循环等待。

  2. 超时机制:为每个锁请求设置超时时间,如果超时则放弃请求,避免长时间等待。

  3. 资源申请策略:在开始执行某个任务之前,优先申请所有所需的资源(如果可以),如果无法获得所有资源,则放弃当前任务。

检测死锁的方法

一种简单的方式是使用资源监控技术。在Python中,可以使用线程的状态监控(例如threading.enumerate()可以查看存在的线程和状态)。但这并不是一个严格的死锁检测。

以下是一个简单的测试程序,可以检测死锁的存在:​​​​​​​

import threading  
import time  

def is_alive(threads):  
    return any(thread.is_alive() for thread in threads)  

# 创建线程并尝试死锁  
def create_deadlock():  
    lock1 = threading.Lock()  
    lock2 = threading.Lock()  

    def thread1():  
        with lock1:  
            time.sleep(1)  # 等待  
            with lock2:  
                print("Thread 1 executed")  

    def thread2():  
        with lock2:  
            time.sleep(1)  # 等待  
            with lock1:  
                print("Thread 2 executed")  

    t1 = threading.Thread(target=thread1)  
    t2 = threading.Thread(target=thread2)  

    t1.start()  
    t2.start()  

    return t1, t2  

# 测试  
threads = create_deadlock()  

# 检测死锁  
while True:  
    if is_alive(threads):  
        print("Threads are still alive, possible deadlock detected.")  
    else:  
        print("All threads finished execution.")  
        break  
    time.sleep(0.5)

总结

死锁是多线程编程中常见的问题,了解其产生原因和防止措施有助于提高程序的稳定性与可靠性。通过实现合理的资源管理与调整锁的获取顺序,可以避免多线程死锁的发生。

最后: 下方这份完整的软件测试视频教程已经整理上传完成,需要的朋友们可以自行领取【保证100%免费】
在这里插入图片描述​​​​
在这里插入图片描述​​​​

评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值