MST

星途 面试题库

面试题:Python中threading模块线程同步机制

在Python的threading模块中,常用的线程同步机制有哪些?请举例说明如何使用`Lock`、`Semaphore`来实现线程同步,并阐述它们之间的区别。
43.5万 热度难度
编程语言Python

知识考点

AI 面试

面试题答案

一键面试

常用线程同步机制

  1. Lock(锁):用于防止多个线程同时访问共享资源,同一时间只有一个线程可以获得锁并执行相关代码,其他线程需等待锁的释放。
  2. Semaphore(信号量):可以控制同时访问共享资源的线程数量,允许多个线程同时访问,但数量受信号量初始值限制。
  3. Condition(条件变量):允许线程在满足特定条件时才执行,线程可以等待某个条件满足并在条件满足时被唤醒。
  4. Event(事件):用于线程间通信,一个线程可以通过设置事件来通知其他线程执行某些操作,其他线程可以等待事件被设置。

使用Lock实现线程同步

import threading

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


def increment():
    global count
    for _ in range(1000000):
        lock.acquire()
        try:
            count += 1
        finally:
            lock.release()


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

for t in threads:
    t.join()

print(f"Final count: {count}")

在上述代码中,Lock对象lock用于确保在对count进行增加操作时,同一时间只有一个线程可以执行,避免了竞态条件。

使用Semaphore实现线程同步

import threading

# 创建一个信号量,允许最多3个线程同时访问
semaphore = threading.Semaphore(3)


def task():
    semaphore.acquire()
    try:
        print(f"{threading.current_thread().name} has entered the critical section.")
        # 模拟一些工作
        import time
        time.sleep(2)
        print(f"{threading.current_thread().name} is leaving the critical section.")
    finally:
        semaphore.release()


threads = []
for i in range(5):
    t = threading.Thread(target=task)
    threads.append(t)
    t.start()

for t in threads:
    t.join()

在这段代码中,Semaphore对象semaphore初始化为3,意味着最多可以有3个线程同时进入临界区执行任务,其他线程需要等待信号量的释放。

Lock和Semaphore的区别

  1. 可同时访问线程数量
    • Lock:同一时间只允许一个线程获得锁并进入临界区,是二元信号量(信号量值为0或1)的一种特殊情况。
    • Semaphore:可以设置允许同时进入临界区的线程数量,初始值大于1时允许多个线程同时访问共享资源。
  2. 应用场景
    • Lock:适用于对共享资源的独占访问,例如对全局变量的修改,以防止数据竞争。
    • Semaphore:适用于需要限制同时访问共享资源的线程数量的场景,比如限制数据库连接池的并发使用数量等。