Domanda

Ho un Thread-Selending classe che dovrebbe eseguire solo un'istanza alla volta (processo incrociato). Per raggiungere questo obiettivo, sto cercando di utilizzare un blocco del file. Ecco i bit del mio codice:

class Scanner(Thread):

  def __init__(self, path):
    Thread.__init__(self)
    self.lock_file = open(os.path.join(config.BASEDIR, "scanner.lock"), 'r+')
    fcntl.lockf(self.lock_file, fcntl.LOCK_EX | fcntl.LOCK_NB)

  # Stuff omitted

  def run(self):
    logging.info("Starting scan on %s" % self.path)

    # More stuff omitted

    fcntl.lockf(self.lock_file, fcntl.LOCK_UN)

Mi aspettavo il lockf Chiama per lanciare un'eccezione se a Scanner Il thread era già in esecuzione e non inizializza affatto l'oggetto. Tuttavia, posso vederlo nel terminale:

INFO:root:Starting scan on /home/felix/Music
INFO:root:Starting scan on /home/felix/Music
INFO:root:Scan finished
INFO:root:Scan finished

Il che suggerisce che due Scanner I thread sono in esecuzione contemporaneamente, nessuna eccezione lanciata. Sono sicuro che mi manca qualcosa di veramente semplice qui, ma non riesco a capire cosa sia. Qualcuno può aiutare?

È stato utile?

Soluzione

Alla fine ho trovato la soluzione. Doveva usare fcntl.flock() invece di fcntl.lockf(), con gli stessi identici parametri. Non sono sicuro del perché ciò abbia fatto la differenza.

Altri suggerimenti

Stai aprendo il file di blocco utilizzando r+ che sta cancellando il file precedente e creando uno nuovo. Ogni thread blocca un file diverso.

Uso w o r+a

Oltre a usare il gregge, ho dovuto aprire anche il file in questo modo:

fd = os.open(lockfile, os.O_CREAT | os.O_TRUNC | os.O_WRONLY)

Non funziona altro saggio.

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top