面试题答案
一键面试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个线程同时获取连接,超过这个数量的线程需要等待,直到有连接被释放。
- 资源限制:当程序需要访问一些有限的资源(如打印机、摄像头等)时,信号量可以用来限制同时访问这些资源的线程数量,确保资源的合理使用。