by @taoqingqiu
案发现场
故事发生在一个用于标注的 web tool 中,勤奋的用户竭尽全力地按下右键,待标注图片飞快地翻动,后台应接不暇地 pickle.load 某个与 image path 相关的变量。忽然,异常发生了。
原因
假设有一个叫 test.dict 的二进制文件,它存储了一个无关紧要的、可 pickle.load 的字典。执行如下代码:
import pickle
f_test = open('test.dict', 'rb')
test_dict = pickle.load(f_test)
test_dict_puppet = pickle.load(f_test)
则:
Traceback (most recent call last):
File "<stdin>", line 5, in <module>
EOFError: Ran out of input
一切了然。
解决
当然,示例中的写法是为了探究原因刻意而为之,现实中,问题出现在多线程(或者多进程)同时 load 同一个变量时,解决方法可以是资源加锁,如下:
import pickle, fcntl
def load_func(var_path: str):
"""
a function will be used in mutiple threads.
"""
result = None
if os.path.exists(var_path):
f_var = open(var_path, 'rb')
fcntl.flock(f_var, fcntl.LOCK_EX) # 默认阻塞、互斥
result = pickle.load(f_var)
fcntl.flock(f_var, fcntl.LOCK_UN) # 解锁后再释放
f_var.close()
return result
就这。