MST

星途 面试题库

面试题:Python线程安全上下文管理与资源池的结合

假设你有一个数据库连接资源池,在多线程环境下,每个线程需要从资源池中获取连接,完成数据库操作后归还连接。请你设计并实现一个线程安全的上下文管理器,用于管理从资源池获取和归还数据库连接的过程。资源池可以用简单的列表模拟,并且要考虑资源池耗尽时的处理逻辑。要求详细说明设计思路,并给出完整的Python代码实现。
49.7万 热度难度
编程语言Python

知识考点

AI 面试

面试题答案

一键面试

设计思路

  1. 资源池管理:使用列表来模拟数据库连接资源池。
  2. 线程安全:为了确保多线程环境下对资源池的安全访问,使用threading.Lock来进行同步控制。
  3. 上下文管理器:利用Python的contextlib.contextmanager装饰器来实现上下文管理器,这样可以方便地使用with语句来管理资源的获取和释放。
  4. 资源耗尽处理:当资源池为空时,线程可以选择等待直到有资源可用,这里通过threading.Condition来实现线程的等待和唤醒机制。

Python代码实现

import threading
from contextlib import contextmanager


class ConnectionPool:
    def __init__(self, size):
        self.pool = [f"Connection-{i}" for i in range(size)]
        self.lock = threading.Lock()
        self.condition = threading.Condition(self.lock)

    def get_connection(self):
        with self.lock:
            while not self.pool:
                self.condition.wait()
            return self.pool.pop()

    def return_connection(self, conn):
        with self.lock:
            self.pool.append(conn)
            self.condition.notify()


@contextmanager
def connection_context(pool):
    conn = pool.get_connection()
    try:
        yield conn
    finally:
        pool.return_connection(conn)


# 示例使用
if __name__ == "__main__":
    pool = ConnectionPool(5)

    def worker():
        with connection_context(pool) as conn:
            print(f"{threading.current_thread().name} using {conn}")


    threads = []
    for _ in range(10):
        t = threading.Thread(target=worker)
        threads.append(t)
        t.start()

    for t in threads:
        t.join()