面试题答案
一键面试- 信号量(Semaphore):用于限制同时访问网站的线程数量。信号量可以看作是一个计数器,允许一定数量的线程同时进入临界区。
- 锁(Lock):用于解决不同类型页面解析任务之间的资源竞争问题。锁可以保证同一时间只有一个线程访问共享资源。
- 避免死锁:
- 按顺序获取锁:所有线程按照相同的顺序获取锁,避免循环依赖。
- 使用超时机制:在获取锁时设置超时时间,如果在规定时间内无法获取锁,则放弃并释放已获取的锁。
关键代码片段(Python 示例)
import threading
import requests
from bs4 import BeautifulSoup
# 信号量,限制同时访问网站的线程数量
semaphore = threading.Semaphore(5)
# 不同类型页面解析任务的锁
lock_type1 = threading.Lock()
lock_type2 = threading.Lock()
def crawl(url, page_type):
with semaphore:
try:
response = requests.get(url)
if response.status_code == 200:
if page_type == 'type1':
with lock_type1:
soup = BeautifulSoup(response.content, 'html.parser')
# 进行 type1 页面的解析任务
pass
elif page_type == 'type2':
with lock_type2:
soup = BeautifulSoup(response.content, 'html.parser')
# 进行 type2 页面的解析任务
pass
except Exception as e:
print(f"Error crawling {url}: {e}")
# 创建并启动线程
urls = ['http://example.com', 'http://example2.com']
page_types = ['type1', 'type2']
threads = []
for url, page_type in zip(urls, page_types):
t = threading.Thread(target=crawl, args=(url, page_type))
threads.append(t)
t.start()
for t in threads:
t.join()
在上述代码中:
semaphore
限制了同时访问网站的线程数量为 5。lock_type1
和lock_type2
分别用于保护type1
和type2
页面解析任务的共享资源,避免资源竞争。- 通过
with
语句,确保在任务完成后自动释放信号量和锁,提高代码的安全性和可读性。