2016-01-04 27 views
0

我正在試着在python 3.4.3中製作一個鎖定文件的玩具示例,但是我沒有得到預期的結果。fcntl文件鎖定示例不能正常工作

我有兩個腳本,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之前附加的行數。

爲什麼我在玩具的例子中使用熊貓和numpy?我將有一個類似的用例,所以我想確保它能與我將使用的對象一起工作。

回答

0

這是解決方案,以防其他人遇到此問題。

我創造,而我做的操作和寫入data.pkl文件,該文件被鎖定,第二個文件lock.lck。在寫入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")