实现思路
- 信号处理:使用
signal
模块捕获系统退出信号(如SIGTERM
和SIGINT
),设置信号处理函数。
- 共享标志:定义一个共享的标志变量,用于通知各个线程需要退出。线程在执行过程中,需要定期检查这个标志。
- 锁机制:为了避免线程间竞争条件,在对共享资源(如文件操作)进行访问时,使用锁(
threading.Lock
)来保证同一时间只有一个线程可以操作。
- 文件管理:每个线程在启动时打开文件,并将文件对象保存在线程本地数据中。在收到退出信号后,线程关闭文件。
关键代码示例
import threading
import signal
import time
# 共享退出标志
exit_flag = False
# 锁
file_lock = threading.Lock()
def worker(file_path):
global exit_flag
local_file = None
try:
# 打开文件
with file_lock:
local_file = open(file_path, 'a')
while not exit_flag:
# 模拟文件写入操作
with file_lock:
local_file.write('Some data\n')
local_file.flush()
time.sleep(1)
except Exception as e:
print(f"线程发生异常: {e}")
finally:
# 关闭文件
if local_file:
with file_lock:
local_file.close()
def signal_handler(sig, frame):
global exit_flag
print('收到退出信号,正在安全退出...')
exit_flag = True
# 注册信号处理函数
signal.signal(signal.SIGTERM, signal_handler)
signal.signal(signal.SIGINT, signal_handler)
# 创建并启动线程
threads = []
file_paths = ['file1.txt', 'file2.txt', 'file3.txt']
for file_path in file_paths:
t = threading.Thread(target=worker, args=(file_path,))
t.start()
threads.append(t)
# 等待所有线程结束
for t in threads:
t.join()
print('所有线程已安全退出')
代码解释
- 共享标志:
exit_flag
用于通知线程需要退出。
- 锁机制:
file_lock
确保文件操作的线程安全。
- worker函数:每个线程执行的函数,打开文件并在未收到退出信号时进行写入操作,在退出时关闭文件。
- signal_handler函数:信号处理函数,设置
exit_flag
为True
,通知线程退出。
- 信号注册:使用
signal.signal
注册SIGTERM
和SIGINT
信号的处理函数。
- 线程创建与启动:创建多个线程并启动,每个线程处理不同的文件。
- 线程等待:主线程使用
join
方法等待所有线程结束。