MST
星途 面试题库

面试题:Python线程中如何处理资源竞争问题

在Python多线程编程中,经常会遇到多个线程同时访问共享资源的情况,从而导致资源竞争问题。请阐述你对Python线程资源竞争的理解,并说明如何使用锁(Lock)、信号量(Semaphore)等机制来解决这一问题。请给出简单的代码示例进行说明。
50.6万 热度难度
编程语言Python

知识考点

AI 面试

面试题答案

一键面试

1. 对Python线程资源竞争的理解

当多个线程同时访问和修改共享资源(如变量、文件、数据库连接等)时,由于线程的执行是抢占式的,可能会导致数据不一致或程序出现错误的现象,这就是资源竞争。例如,一个线程读取共享变量的值,在它对该值进行修改之前,另一个线程也读取了同样的值并进行修改,这样就会导致第一个线程修改的值被覆盖,最终得到的结果与预期不符。

2. 使用锁(Lock)解决资源竞争问题

锁是一种简单的同步机制,它有两种状态:锁定(locked)和未锁定(unlocked)。当一个线程获取到锁(将其状态设为锁定),其他线程就无法获取该锁,直到该线程释放锁(将其状态设为未锁定)。这样可以确保在同一时刻只有一个线程能够访问共享资源。

示例代码:

import threading

# 共享资源
counter = 0
# 创建锁对象
lock = threading.Lock()

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

# 创建两个线程
thread1 = threading.Thread(target=increment)
thread2 = threading.Thread(target=increment)

# 启动线程
thread1.start()
thread2.start()

# 等待线程结束
thread1.join()
thread2.join()

print(f"最终的计数器值: {counter}")

3. 使用信号量(Semaphore)解决资源竞争问题

信号量是一个计数器,它允许一定数量的线程同时访问共享资源。当一个线程获取信号量时,计数器减1;当一个线程释放信号量时,计数器加1。当计数器为0时,其他线程无法获取信号量,只能等待。

示例代码:

import threading

# 共享资源
counter = 0
# 创建信号量对象,允许同时2个线程访问
semaphore = threading.Semaphore(2)

def increment():
    global counter
    for _ in range(1000000):
        # 获取信号量
        semaphore.acquire()
        try:
            counter += 1
        finally:
            # 释放信号量
            semaphore.release()

# 创建多个线程
threads = []
for _ in range(5):
    thread = threading.Thread(target=increment)
    threads.append(thread)
    thread.start()

# 等待所有线程结束
for thread in threads:
    thread.join()

print(f"最终的计数器值: {counter}")