MST

星途 面试题库

面试题:Python装饰器与上下文管理器结合处理资源竞争问题

假设有一个多线程环境下对共享资源(如文件操作)的函数操作,你需要结合Python的装饰器和上下文管理器来确保资源竞争不会发生。请设计并实现相关的装饰器和上下文管理器代码,描述你的设计思路以及如何防止资源竞争。
24.0万 热度难度
编程语言Python

知识考点

AI 面试

面试题答案

一键面试

设计思路

  1. 上下文管理器:使用contextlib.contextmanager装饰器创建上下文管理器,在进入上下文时获取锁,离开上下文时释放锁,以此来确保共享资源在同一时间只有一个线程能访问。
  2. 装饰器:利用上下文管理器,在被装饰函数执行前进入上下文(获取锁),执行后离开上下文(释放锁),从而防止多线程环境下对共享资源的资源竞争。

代码实现

import threading
import contextlib


@contextlib.contextmanager
def resource_lock():
    lock = threading.Lock()
    lock.acquire()
    try:
        yield
    finally:
        lock.release()


def thread_safe_resource_operation(func):
    def wrapper(*args, **kwargs):
        with resource_lock():
            return func(*args, **kwargs)

    return wrapper


# 模拟文件操作的共享资源函数
@thread_safe_resource_operation
def file_operation():
    print("Performing file operation...")


# 测试多线程环境
threads = []
for _ in range(5):
    t = threading.Thread(target=file_operation)
    threads.append(t)
    t.start()

for t in threads:
    t.join()

防止资源竞争的原理

  1. 锁机制threading.Lock是线程锁,在任何时刻只有一个线程可以获得锁。当一个线程获取锁后,其他线程尝试获取锁时会被阻塞,直到该线程释放锁。
  2. 上下文管理器:通过resource_lock上下文管理器,确保在进入with语句块时获取锁,离开with语句块时释放锁,这样就保证了在with语句块内的代码(即共享资源操作部分)同一时间只有一个线程在执行。
  3. 装饰器thread_safe_resource_operation装饰器将被装饰函数的执行部分包裹在with resource_lock()语句块内,从而使得被装饰的共享资源操作函数在多线程环境下可以安全执行,避免资源竞争。