MST

星途 面试题库

面试题:Python中threading模块的常用功能函数及应用场景

请详细介绍Python threading模块中的`Thread`类、`Lock`、`Semaphore`这几个功能函数,并且举例说明它们在实际项目中的应用场景。
49.1万 热度难度
编程语言Python

知识考点

AI 面试

面试题答案

一键面试

Thread

Thread类是threading模块中用于创建和管理线程的类。它允许你在Python程序中并发执行多个线程。

创建线程: 可以通过继承Thread类并重写run方法,或者直接传递一个函数给Thread类的构造函数来创建线程。

import threading


# 继承Thread类
class MyThread(threading.Thread):
    def run(self):
        print(f"{self.name} is running")


# 直接传递函数
def worker():
    print(f"{threading.current_thread().name} is working")


if __name__ == '__main__':
    # 继承方式创建线程
    t1 = MyThread()
    t1.start()

    # 函数方式创建线程
    t2 = threading.Thread(target=worker)
    t2.start()

应用场景

  • 网络爬虫:可以使用多线程同时请求多个网页,提高爬取效率。比如在一个爬虫项目中,有多个URL需要抓取数据,每个URL的抓取可以分配到一个线程,这样可以并行处理,加快数据获取速度。
  • 实时数据处理:在处理实时数据(如传感器数据)时,一个线程可以负责数据的读取,另一个线程负责数据的分析和处理,确保数据的实时性。

Lock

Lock(锁)是一种同步原语,用于防止多个线程同时访问共享资源,避免数据竞争和不一致的问题。

使用方法

import threading

lock = threading.Lock()
counter = 0


def increment():
    global counter
    lock.acquire()
    try:
        counter += 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 counter value: {counter}")

应用场景

  • 数据库操作:多个线程可能同时需要对数据库进行读写操作。使用锁可以确保在同一时间只有一个线程能够访问数据库,避免数据冲突。例如,在一个银行转账的程序中,多个线程可能同时进行转账操作,通过锁可以保证账户余额的更新是正确的。
  • 文件操作:当多个线程需要写入同一个文件时,为了避免文件内容混乱,使用锁来确保每次只有一个线程可以写入文件。

Semaphore

Semaphore(信号量)是一个计数器,用于控制对共享资源的访问数量。它允许一定数量的线程同时访问共享资源。

使用方法

import threading
import time


semaphore = threading.Semaphore(3)


def task():
    semaphore.acquire()
    try:
        print(f"{threading.current_thread().name} acquired semaphore")
        time.sleep(2)
        print(f"{threading.current_thread().name} released semaphore")
    finally:
        semaphore.release()


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

for t in threads:
    t.join()

应用场景

  • 连接池:在数据库连接池或网络连接池中,信号量可以用来控制同时使用的连接数量。例如,数据库连接池可能只允许10个线程同时获取连接,超过这个数量的线程需要等待,直到有连接被释放。
  • 资源限制:当程序需要访问一些有限的资源(如打印机、摄像头等)时,信号量可以用来限制同时访问这些资源的线程数量,确保资源的合理使用。