Python 多进程操作文件时文件锁失效问题如何解决?
import multiprocessing
import json
import time
import fcntl
def init():
with open(‘list.txt’, ‘w’) as f:
f.write(json.dumps({‘sids’: {}}))
def list(data=None):
if data is None:
with open(‘list.txt’, ‘r’) as f:
fcntl.lockf(f.fileno(), fcntl.LOCK_EX)
print(f.read())
return json.loads(f.read())
else:
with open(‘list.txt’, ‘w’) as f:
fcntl.lockf(f.fileno(), fcntl.LOCK_EX)
f.write(json.dumps(data))
def generate(sid):
target = ‘http://www.baidu.com’
data = list()
data[‘sids’][sid] = target
print(len(data[‘sids’]))
list(data)
time.sleep(5)
if name == ‘main’:
init()
processes = []
for i in range(100):
p = multiprocessing.Process(target=generate, args=(i,))
processes.append§
p.start()
for p in processes:
p.join()
几乎所有进程都报 json 解码错误
raise ValueError("No JSON object could be decoded")
ValueError: No JSON object could be decoded
这是哪里出了问题?
Python 多进程操作文件时文件锁失效问题如何解决?
data[‘sids’][sid] = target
print(len(data[‘sids’]))
sid from ???
试试 list 函数直接把 f 返回出去, 并且让外部一直持有这个对象
之前碰到过类似的问题. 写了个
def lock (filename) 这样的函数
一直不生效
应该是在函数内部打开文件, 文件对象在函数完成后就关闭了. 锁也释放了
python<br>def set_lock(block=False):<br> lock_f = open(os.path.join(os.path.dirname(os.path.abspath(sys.argv[0])),<br> '.{0}.lock'.format(os.path.splitext(os.path.basename(sys.argv[0]))[0])), 'w')<br> if block:<br> fcntl.flock(lock_f.fileno(), fcntl.LOCK_EX)<br> else:<br> fcntl.flock(lock_f.fileno(), fcntl.LOCK_EX | fcntl.LOCK_NB)<br> return lock_f<br>
Python 3.6.2 (v3.6.2:5fd33b5, Jul 8 2017, 04:57:36) [MSC v.1900 64 bit (AMD64)] on win32
Type “help”, “copyright”, “credits” or “license” for more information.
>>> data = list()
>>> target = ‘http://www.baidu.com’
>>> data[‘sids’][0] = target
Traceback (most recent call last):
File “<stdin>”, line 1, in <module>
TypeError: list indices must be integers or slices, not str
直接报错了,真的能这么写吗
我怎么觉得问题在这里
print(f.read())
return json.loads(f.read())
你读了两遍,写的时候却只写了一遍
lockf -> flock 试试,参考 https://stackoverflow.com/questions/28470246/python-lockf-and-flock-behaviour
你的 lock 用错了。lockf 对每一个人进程的 file descriptor 都是独立的,所以没用。
官方文档: https://docs.python.org/3/library/fcntl.html
#5 是有这个问题,去掉 print 后有少部分进程报 raise ValueError(“No JSON object could be decoded”)错误
#4 list 是我自定义的函数,不是定义了一个列表。。。命名问题是我的锅。。。函数返回的是一个字典。
#6 试过了,一样的问题
刚才试了一下,这句话确实有问题,第二遍的时候 buffer 应该是空了
#10 本来应该写 100 个,现在每次都有那么 4,5 个写失败。。。感觉这文件锁和假的一样。。。
file lock 在打开文件之前获取,你把 fcntl.lockf(f.fileno(), fcntl.LOCK_EX)提到 open file 前面
你在 open 之前根本就没有 f 这个对象,怎么 lock
6 楼正解


