2010-05-09 11 views
11

Ho uno script in python che utilizza una risorsa che non può essere utilizzata da più di una certa quantità di script simultanei in esecuzione.Semaphores con nome in Python?

Classicamente, questo sarebbe risolto da un semaforo con nome ma non riesco a trovare quelli nella documentazione del modulo multiprocessing o threading.

Mi manca qualcosa o sono denominati semafori non implementati/esposti da Python? e ancora più importante, se la risposta è no, qual è il modo migliore per emularne uno?

Grazie, Boaz

PS. Per ragioni che non sono così rilevanti per questa domanda, non posso aggregare l'attività a un processo/demone continuamente in esecuzione o lavorare con processi generati, entrambi i quali, a quanto pare, avrebbero funzionato con l'API python.

risposta

4

Suggerisco un'estensione di terze parti come these, idealmente lo posix_ipc - vedere in particolare la sezione sempahore nei documenti.

Questi moduli si riferiscono principalmente all'esposizione del "sistema V IPC" (compresi i semafori) in modo unioco, ma almeno uno di essi (posix_ipc in particolare) viene utilizzato per funzionare con Cygwin su Windows (non ho verificato che Richiesta). Ci sono alcuni documenti limitations su FreeBSD 7.2 e Mac OSX 10.5, quindi fai attenzione se quelle piattaforme sono importanti per te.

0

È possibile emularli utilizzando il file system anziché il percorso del kernel (i semafori denominati vengono comunque implementati in alcune piattaforme). Dovrai implementare lo stesso sem_[open|wait|post|unlink], ma dovrebbe essere relativamente banale farlo. Il sovraccarico di sincronizzazione potrebbe essere significativo (a seconda della frequenza con cui devi trafficare con il semaforo nella tua app), quindi potresti voler inizializzare un ramdisk quando avvii il processo in cui memorizzare i semafori con nome.

In alternativa, se non ti senti a tuo agio, potresti probabilmente concludere il boost::interprocess::named_semaphore (docs here) in un semplice modulo di estensione.

+2

Ci sono molti modi per sbagliare (equità, programmazione sveglia, condizioni di gara). Usa primitive kernel o libc (ad esempio la vera sem_ * API, o l'API CreateSemaphore/event in windows); evitare di far ruotare le proprie primitive di sincronizzazione. –

+1

Questo è il motivo per cui offro che potresti usare boost se non ti senti a tuo agio. –