2013-02-25 10 views
6

This articolo precisa, cheSu quali sistemi/filesystem è os.open() atomico?

fd = os.open('foo.lock', os.O_CREAT|os.O_EXCL|os.O_RDWR) 

"è atomica sulla maggior parte dei file system". È vero (su Unix e Windows)? Su quali file system?

Il docs stato che menzionati bandiere sono disponibili su Unix e Windows, in modo che si presenta come un allettante, il metodo multi-piattaforma per il blocco dei file (le bandiere O_CREAT e O_EXCL assicurare che il processo chiamante crea il file).

+3

Questo fallirà a caso sui filesystem NFS anche se non dovrebbe. Sospetto che ce ne siano altri (ad esempio gmail-fs) che non garantiscono l'esclusività e sarebbe straordinariamente difficile determinare se 'foo.lock' si trova su una montatura semanticamente corretta. – msw

+1

@msw: buona cattura.I server NFS, per protocollo, non mantengono uno stato "aperto" per un file, quindi la semantica 'O_EXCL' (sia aperta che creata) su NFS è soggetta a razze. Vedi http://lwn.net/Articles/252012/ per il background tecnico. –

+1

In realtà, la [man-page [Linux open (2)] (http://man7.org/linux/man-pages/man2/open.2.html) dice "Su NFS, O_EXCL è supportato solo quando si usa NFSv3 o più avanti nel kernel 2.6 o successivo ", ma l'autore del post puntato da FrankH. ancora consiglia di non farlo –

risposta

4

per UN * X-compliant (POSIX certificato/IEEE 1003.1 secondo le OpenGroup) sistemi, il comportamento è garantita come le OpenGroups specifiche per open(2)mandato questo. Citazione:

O_EXCL
Se O_CREAT e O_EXCL sono impostati, open() si fallisce se il file esiste. Il controllo dell'esistenza del file e la creazione del file, se non esiste, è atomico rispetto ad altri thread che eseguono open() con lo stesso nome file nella stessa directory con O_EXCL e O_CREAT impostato. Se O_EXCL e O_CREAT sono impostati, e il percorso nomina un collegamento simbolico, open() avrà esito negativo e imposterà errno su [EEXIST], indipendentemente dal contenuto del collegamento simbolico. Se O_EXCL è impostato e O_CREAT non è impostato, il risultato non è definito.

I sistemi UN * X e UN * X-come "comuni" (Linux, MacOSX, * BSD, Solaris, AIX, HP/UX) sicuramente si comportano in quel modo.

Poiché l'API di Windows non ha open() come tale, la funzione di libreria è necessariamente reimplementata in termini di API nativa ma è possibile mantenere la semantica.

Non so quali sistemi ampiamente utilizzati non corrispondono a; QNX, pur non essendo certificato POSIX, ha la stessa dichiarazione nei suoi documenti per open(). Le manpage * BSD non menzionano esplicitamente l '"atomicità" ma Free/Net/OpenBSD lo implementa. Anche gli esotici come SymbianOS (che come Windows non ha una chiamata di sistema UN * X-ish open) possono eseguire l'apertura/creazione atomica.

Per risultati più interessanti, cercare di trovare una libreria di runtime del sistema operativo/C che ha open() ma non significa implementare la semantica di cui sopra per esso ... e su cui Python sarebbe correre con fili (avete ottenuto lì, MSDOS ...).

Modifica: Il mio post si concentra in particolare su "quali sistemi operativi hanno questa caratteristica per open?" - per cui la risposta è "praticamente tutti". WRT. a filesystem però, il quadro è diverso, perché filesystem di rete - se NFS, SMB/CIFS o altri, non sempre mantengono O_EXCL in quanto ciò potrebbe causare denial-of-service (se un cliente fa un open(..., O_EXCL, ...) e poi semplicemente smette di parlare con il fileserver/è spento, tutti gli altri sarebbero bloccati).

+6

'O_EXCL' non lo fa. L'unica cosa 'O_EXCL' è che la chiamata fallisce se il file esiste e' O_CREAT' è specificato. –