fcntl文件锁示例不起作用

时间:2016-01-04 16:01:18

标签: python-3.x

我试图在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?我将有一个类似的用例,所以我想确保它适用于我将要使用的对象。

1 个答案:

答案 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")