Python使用线程读取文件内容存入外部变量为空问题求解
问题成因
你遇到的空字典问题和文件读取操作本身无关,是多线程执行时序导致的:
- 调用
t.start()后,子线程和主线程并行执行,文件读取属于IO操作,本身有耗时,子线程还没完成字典写入逻辑时,主线程已经执行到了打印line_dict的代码,所以此时拿到的是空字典 - 没有文件读取操作时,子线程逻辑执行耗时极短,大概率能在主线程打印前完成字典写入,所以你会误以为运行正常
- 另外你的锁使用不规范:仅在子线程写字典时加锁,主线程读字典时没有加锁,存在竞态条件风险,可能读到被部分修改的字典内容
额外提示:请确认
./lines.txt文件路径正确、存在且有读取权限,否则子线程会抛出文件不存在异常,也会导致字典没有被写入。
解决方法
方法1:调整主线程访问变量的时机,等子线程执行完成后再读取
将主线程的打印逻辑移到t.join()之后,join()会阻塞主线程直到子线程执行结束,保证读取时字典已经被完整写入:
import threading import os def thread_function(filename: str, line_dict: dict, lock:threading.Lock): lock.acquire(blocking=True, timeout=5.8) with open(filename, 'r') as f: for id,line in enumerate(f): line_dict['line{}'.format(id)] = line lock.release() print('[from thread] Keys in Dictionary: \n{}'.format(line_dict.keys())) line_dict = {} lock = threading.Lock() if __name__ == '__main__': t = threading.Thread(target=thread_function, args=('./lines.txt', line_dict, lock)) t.start() t.join() # 等子线程执行完成后再打印 print('[from main] Keys in Dictionary: \n{}'.format(line_dict.keys()))
方法2:主线程访问共享变量时同样加锁
如果需要在子线程执行过程中读取字典内容,主线程读取时也要持有同一把锁,保证读写互斥:
if __name__ == '__main__': t = threading.Thread(target=thread_function, args=('./lines.txt', line_dict, lock)) t.start() # 读取前加锁 lock.acquire(blocking=True, timeout=10) print('[from main] Keys in Dictionary: \n{}'.format(line_dict.keys())) lock.release() t.join()
如果加锁时子线程还持有锁,主线程会阻塞到子线程释放锁后再执行读取,也能保证读取到完整内容。
内容的提问来源于stack exchange,提问作者kneelb4darth
相关产品推荐
相关产品推荐

