9

Possiedo un'unità di rete (Z: \) condivisa da più computer Windows. È possibile implementare un blocco cross-machine semplicemente creando/eliminando file su questa unità di rete?Implementazione del blocco distribuito utilizzando i file

Ad esempio, due computer, A e B, desiderano scrivere su una risorsa condivisa con un ID di 123 allo stesso tempo.

Uno dei computer, ad esempio A, blocca prima la risorsa creando un file vuoto Z: \ locks \ 123. Quando B vede che c'è il file di lock con il nome di "123", B sa che la risorsa 123 viene utilizzata da qualcun altro, quindi deve aspettare che Z: \ locks \ 123 sia cancellato da A prima che possa accedere al risorsa.

È come una sezione critica nel multithreading, ma voglio farlo su più macchine.

Sto provando a implementare in Python. Ecco quello che mi si avvicinò con:

import os 
import time 


def lock_it(lock_id): 

    lock_path = "Z:\\locks\\" + lock_id 
    while os.path.exists(lock_path): 
     time.sleep(5) # wait for 5 seconds 

    # create the lock file 
    lock_file = open(lock_path, "w") 
    lock_file.close() 


def unlock_it(lock_id): 

    # delete the lock file 
    lock_path = "Z:\\locks\\" + lock_id 
    if os.path.exists(lock_path): 
     os.remove(lock_path) 

questo non funzionerà, perché ci potrebbero essere più di uno dei processi uscire dallo stato di attesa e creare il file di blocco, allo stesso tempo.

Quindi, ancora una volta, la domanda è: È possibile implementare un meccanismo di blocco incrociato su una memoria condivisa?

risposta

5

... una specie di.

Innanzitutto, è necessario creare una directory di blocco anziché un file di blocco. Creazione di una directory (vedi os.mkdir) avrà esito negativo se la directory esiste già, in modo da poter acquisire il blocco in questo modo:

while True: 
    try: 
     os.mkdir(r"z:\my_lock") 
     return 
    except OSError as e: 
     if e.errno != 21: # Double check that errno will be the same on Windows 
      raise 
     time.sleep(5) 

Secondo (e questo è dove il "sorta di" entra in gioco) si vorrà un po ' modo di notare quando la persona che tiene il lucchetto è morta. Un modo semplice per farlo potrebbe essere quello di aggiornare occasionalmente un file all'interno della directory di blocco. Quindi, se i client notano che il file non è stato aggiornato da un po 'di tempo, possono rimuovere la directory e provare ad acquisire il blocco da soli.

+1

Come aggiungere un timeout? Ad esempio, dopo un periodo di tempo, diciamo 60 secondi, il blocco viene rilasciato automaticamente. Supponendo che il tempo di blocco non superi questo timeout. Posso ottenere il tempo di blocco con time.time() - os.path.getctime ("Z: \ my_lock") per verificare se un blocco è in ritardo. – eliang

2

Questo non funzionerà così bene come si potrebbe sperare. Avrai altri problemi come l'unità di rete che va via, nel qual caso tutti i processi saranno bloccati o penseranno che nessuno è in possesso di un lucchetto.

Ti suggerisco di dare un'occhiata a qualcosa come ZooKeeper. Sarai in grado di creare blocchi sincroni e recuperare in caso di guasti della rete. Il framework dietro i blocchi distribuiti è molto più complesso di creare un file su un'unità di rete.

+0

Stavo pensando a software Memcache o in coda come Beanstalk. – aitchnyu