我想在python中通过多个线程读写一个json文件。
初始设置) open(file_path, "w+") (如果文件是空的,就直接转储空的json文件)
当用threading.lock编写时
1) 在内存中加载json文件。
2) 通过新的键和值更新内存中加载的json。
3) dump current json(on memory) to file.
因为在写的时候有一个锁,我认为即使有多个线程运行,读和写文件也是安全的,但是会出错。
class Writer(object):
def __init__(self, path):
self._lock = threading.Lock()
self.path = path
self.current_json = None
self._init_opend_file()
def _init_opend_file(self):
with self._lock:
self._opened_file = open(self.path, "w+")
if self._opened_file.read() == "":
json.dump({}, self._opened_file)
else:
def write(self, key, value):
with self._lock:
self._opened_file.seek(0)
self.current_json = json.load(self._opened_file)
self.current_json[key] = value
self._opened_file.seek(0)
self._opened_file.truncate()
json.dump(self.current_json, self._opened_file)
if __name__ == "__main__":
path = r"D:\test.json"
def run(name, range_):
writer = Writer(path)
for i in range(range_):
writer.write(name,i)
t1 = threading.Thread(target=run, args=("one", 1000))
t2 = threading.Thread(target=run, args=("two", 2000))
t1.start()
t2.start()
我希望在test.json中得到{"一":1000,"二":2000}。但我得到的是{"一"。1}"二"。1}.似乎多个线程同时访问该文件,并写入不同的东西 但是,我不能不理解为什么会发生threading.lock()的情况。
Exception in thread Thread-2:
Traceback (most recent call last):
File "D:\Anaconda3_64\envs\atom\lib\threading.py", line 917, in _bootstrap_inner
self.run()
File "D:\Anaconda3_64\envs\atom\lib\threading.py", line 865, in run
self._target(*self._args, **self._kwargs)
File "D:/Dropbox/000_ComputerScience/000_개발/Quant/Seperator/json_test.py", line 37, in run
writer.write(name,i)
File "D:/Dropbox/000_ComputerScience/000_개발/Quant/Seperator/json_test.py", line 24, in write
self.current_json = json.load(self._opened_file)
File "D:\Anaconda3_64\envs\atom\lib\json\__init__.py", line 296, in load
parse_constant=parse_constant, object_pairs_hook=object_pairs_hook, **kw)
File "D:\Anaconda3_64\envs\atom\lib\json\__init__.py", line 348, in loads
return _default_decoder.decode(s)
File "D:\Anaconda3_64\envs\atom\lib\json\decoder.py", line 337, in decode
obj, end = self.raw_decode(s, idx=_w(s, 0).end())
File "D:\Anaconda3_64\envs\atom\lib\json\decoder.py", line 355, in raw_decode
raise JSONDecodeError("Expecting value", s, err.value) from None
json.decoder.JSONDecodeError: Expecting value: line 1 column 1 (char 0)