MST

星途 面试题库

面试题:Python threading模块实用函数与线程同步

假设你正在开发一个多线程的Python程序,使用threading模块,其中多个线程需要访问和修改共享资源。请阐述如何合理运用threading模块中的实用函数(如Lock、Semaphore等)来确保线程安全,避免数据竞争和不一致问题,并通过示例代码说明。
45.6万 热度难度
编程语言Python

知识考点

AI 面试

面试题答案

一键面试

确保线程安全的方法

  1. Lock(互斥锁)
    • 原理:Lock是一种简单的同步原语,它只有两种状态:锁定和未锁定。当一个线程获取了Lock,其他线程就不能再获取,直到该线程释放Lock。这确保了同一时间只有一个线程可以访问共享资源,从而避免数据竞争。
  2. Semaphore(信号量)
    • 原理:Semaphore管理一个内部计数器,当调用acquire()时计数器减1,调用release()时计数器加1。当计数器为0时,acquire()会阻塞,直到其他线程调用release()增加计数器。它可以用来控制同时访问共享资源的线程数量。

示例代码

  1. 使用Lock
import threading

# 共享资源
shared_variable = 0
lock = threading.Lock()


def increment():
    global shared_variable
    for _ in range(100000):
        # 获取锁
        lock.acquire()
        try:
            shared_variable += 1
        finally:
            # 释放锁
            lock.release()


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

for t in threads:
    t.join()

print(f"Final value of shared_variable: {shared_variable}")
  1. 使用Semaphore
import threading

# 共享资源
shared_resource_list = []
semaphore = threading.Semaphore(3)  # 允许最多3个线程同时访问


def access_shared_resource():
    semaphore.acquire()
    try:
        shared_resource_list.append(threading.current_thread().name)
        print(f"{threading.current_thread().name} accessed the shared resource.")
    finally:
        semaphore.release()


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

for t in threads:
    t.join()

print(f"Shared resource list: {shared_resource_list}")

在上述示例中,使用Lock确保同一时间只有一个线程可以修改shared_variable,避免数据竞争。使用Semaphore限制同时访问shared_resource_list的线程数量为3,防止过多线程同时操作导致资源过度使用或不一致问题。