[Python] Mettere in pausa gli altri threads

Manlio Perillo manlio.perillo a gmail.com
Mer 9 Ott 2013 12:40:49 CEST


On 09/10/2013 12:02, Luca wrote:
> [...]
>
>   - Ho una lista di files che viene generata tramite filtri di
> inclusione e/o esclusione.
>   - Questa lista viene passata al ciclo che esegue la copia file per file.
>   - Per ogni file viene lanciato un Thread (con possibilità di limitare
> il numero di thread)
>   - Durante la copia uno o più o tutti i file possono essere già
> presenti nella/e cartella/e di destinazione.
>   - In caso venga chiamato con il parametro --overwrite=ASK, lo script,
> al PRIMO file esistente che trova deve bloccare tutto quindi:

Secondo me ti stai complicando la vita, ma di brutto!

>     1 - Threads già avviati ma che non hanno ancora fatto la verifica di
> os.path.exists (in effetti se è il primo gli altri non ci sono ancora
> arrivati)
>     2 - Ovviamente bloccare eventuali nuovi thread sul nascere.

La 2 non ha senso, in un programma "normale" (ovviamente IMHO).

>     3 - Attendere una risposta dall'utente.
>     4 - Reimpostare il parametro overwrite *globale*.
>     5 - Riprendere da dove si era fermato.
>
> A questo punto l'overwrire non sarà più ASK ma YES o NO, a seconda dei
> casi, e i rimanenti thread si comporteranno di conseguenza.
>

Devi ripensare alla logica del programma.

Una possibilità è avere l'overwrite settato in partenza, tramite opzione.

Un'altra possibilità è di fare quanto segue (non testato):

1) hai un thread pool con cui interagisci tramite queue.
    Purtroppo la libreria standard di Python non ha una thread pool, ma
    solo un process pool.
2) al thread pool **non** passi il path del file, ma il descrittore di
    file, in modo da evitare possibili race conditions (che non so
    tradurre in italiano)
3) in un thread separato (visto che tanto vuoi usare i thread)
    iteri sulla lista di file, e per ciascun file:

      * apri il file di origine (O_RDONLY)
      * apri il file di destinazione, secondo questa modalità:
        - se `overwrite` è true, lo apri in modalità normale
          (O_CREAT | O_WRONLY)
        - se `overwrite` è false, lo apri i modalità esclusiva
          (O_CREAT | O_EXCL | O_WRONLY) e se fallisce salti la copia
        - se `overwirite` è ask, apri il file in modalità esclusiva,
          e se fallisce chiedi se sovrascrivere il file o meno, e lo
          riapri di conseguenza secondo i punti precedenti
          (O_CREAT | O_WRONLY, oppure O_CREAT | O_EXCL | O_WRONLY)
      * passi i due descrittori di file al thred pool
      * se il pool è pieno, l'operazione precedente (queue.put)
        bloccherà fino a quando non si libera uno slot, quindi non devi
        preoccuparti di cose strane, come bloccare nuovi thread sul
        nascere

    Nota che volendo, puoi aprire il file di origine nel thread pool.

 > [...]


Ciao  Manlio


Maggiori informazioni sulla lista Python