我试图在python 3.4.3中训练锁定文件的玩具示例,但是我没有得到预期的结果。
我有两个脚本,script1.py和script2.py:
#script1.py
import pickle
import pandas as pd
import numpy as np
import time
import fcntl
df = pd.DataFrame.from_dict({"script_id": [0], "val1": [0], "val2": [0]})
df.to_pickle("data.pkl")
for i in range(500):
f = open("data.pkl", "rb+")
while True:
try:
# lock if unlocked
fcntl.flock(f, fcntl.LOCK_EX | fcntl.LOCK_NB)
break
except:
time.sleep(0.01)
df.loc[i, :] = np.concatenate([np.array([1]), np.random.sample(2)])
time.sleep(np.random.uniform(0, 0.05))
pickle.dump(df, f)
# unlock when done
fcntl.flock(f, fcntl.LOCK_UN)
f.close()
第二个脚本非常相似:
import pickle
import pandas as pd
import numpy as np
import time
import fcntl
f = open("data.pkl", "rb")
while True:
try:
fcntl.flock(f, fcntl.LOCK_EX | fcntl.LOCK_NB)
df = pickle.load(f)
fcntl.flock(f, fcntl.LOCK_UN)
f.close()
break
except:
time.sleep(0.001)
for i in range(500, 1000):
f = open("data.pkl", "rb+")
while True:
try:
# lock if unlocked
fcntl.flock(f, fcntl.LOCK_EX | fcntl.LOCK_NB)
break
except:
time.sleep(0.01)
df.loc[i, :] = np.concatenate([np.array([2]), np.random.sample(2)])
time.sleep(np.random.uniform(0, 0.05))
pickle.dump(df, f)
# unlock when done
fcntl.flock(f, fcntl.LOCK_UN)
f.close()
这个想法是两个脚本应该读取和写入同一个文件,并有一些人为的延迟。
每个脚本都会向从data.pkl加载的数据帧添加一个随机行,它总计最多1000行。
我首先运行script1
,然后尽可能快地运行script2
。我最终得到500 + n
行数据框,其中n
是我运行script2之前追加的行数。
为什么我在玩具示例中使用pandas和numpy?我将有一个类似的用例,所以我想确保它适用于我将要使用的对象。
答案 0 :(得分:0)
以下是解决方案,以防其他人遇到此问题。
我创建了第二个文件lock.lck
,当我执行操作并写入data.pkl
文件时,该文件被锁定。写完data.pkl
后,锁定就会被释放。
# script1.py
import pandas as pd
import numpy as np
import time
import fcntl
df = pd.DataFrame.from_dict({"script_id": [0], "val1": [0], "val2": [0]})
df.to_pickle("data.pkl")
for i in range(500):
with open("lock.lck", "r") as f_lock:
fcntl.flock(f_lock, fcntl.LOCK_EX)
time.sleep(np.random.uniform(0, 0.05))
df = pd.read_pickle("data.pkl")
df.loc[i, :] = np.concatenate([np.array([1]), np.random.sample(2)])
df.to_pickle("data.pkl")
现在是第二个脚本:
# script2.py
import pandas as pd
import numpy as np
import time
import fcntl
for i in range(500,1000):
with open("lock.lck") as f_lock:
fcntl.flock(f_lock, fcntl.LOCK_EX)
time.sleep(np.random.uniform(0, 0.05))
df = pd.read_pickle("data.pkl")
df.loc[i, :] = np.concatenate([np.array([2]), np.random.sample(2)])
df.to_pickle("data.pkl")