os.path.exists () liegt

8

Ich führe eine Reihe von Python-Skripten auf einem Linux-Cluster aus, und die Ausgabe von einem Job ist normalerweise die Eingabe in ein anderes Skript, das möglicherweise auf einem anderen Knoten ausgeführt wird. Ich finde, dass es einige nicht unbedeutende Verzögerungen gibt, bevor Python Dateien bemerkt, die auf anderen Knoten erstellt wurden - os.path.exists () gibt false zurück und open () schlägt ebenfalls fehl. Ich kann eine Weile nicht os.path.exists (Mypath) Schleife, bis die Datei erscheint, und es kann mehr als eine volle Minute dauern, die nicht optimal in einer Pipeline mit vielen Schritten und potenziell viele Datensätze parallel laufen.

Die einzige Problemumgehung, die ich bisher gefunden habe, ist subprocess.Popen ("ls% s"% (pathdir), shell = True) aufzurufen, was das Problem magisch behebt. Ich denke, das ist wahrscheinlich ein Systemproblem, aber irgendwie könnte Python dies verursachen? Irgendeine Art von Cache oder etwas? Mein Systemadministrator war bisher nicht sehr hilfreich.

    
Noah 24.06.2010, 17:48
quelle

2 Antworten

9

os.path.exists() ruft nur die Funktion stat() der C-Bibliothek auf.

Ich glaube, dass Sie in der Kernel-NFS-Implementierung in einen Cache laufen. Im Folgenden finden Sie einen Link zu einer Seite, auf der das Problem beschrieben wird, sowie einige Methoden zum Leeren des Cache.

  

Dateihandle Caching

     

Verzeichnisse cachen Dateinamen in Dateizugriffsnummern. Die häufigsten Probleme dabei sind:

     

• Sie haben eine geöffnete Datei, und Sie müssen überprüfen, ob die Datei durch eine neuere Datei ersetzt wurde. Sie müssen den Dateihandle-Cache des übergeordneten Verzeichnisses leeren, bevor stat () die Informationen der neuen Datei und nicht die der geöffneten Datei zurückgibt.

     

this Tatsächlich hat dieser Fall ein anderes Problem: Die alte Datei wurde möglicherweise gelöscht und durch eine neue Datei ersetzt, aber beide Dateien können den gleichen Inode haben. Sie können diesen Fall überprüfen, indem Sie den Attributcache der geöffneten Datei leeren und dann sehen, ob fstat () mit ESTALE fehlschlägt.

     

• Sie müssen prüfen, ob eine Datei existiert. Zum Beispiel eine Sperrdatei. Kernel hat möglicherweise zwischengespeichert, dass die Datei nicht existiert, auch wenn es in Wirklichkeit ist. Sie müssen den negativen Dateizugriffsspeicher des übergeordneten Verzeichnisses leeren, um zu sehen, ob die Datei wirklich existiert.

     

Einige Möglichkeiten zum Leeren des Dateizugriffs-Cache:

     

• Wenn sich der mtime des übergeordneten Verzeichnisses ändert, wird der Cache des Dateihandle gelöscht, indem der Attributcache geleert wird. Dies sollte sehr gut funktionieren, wenn der NFS-Server eine Auflösung im Nanosekunden- oder Mikrosekundenbereich unterstützt.

     

• Linux: chown () das Verzeichnis zu seinem aktuellen Besitzer. Der Dateizugriffsspeicher wird geleert, wenn der Aufruf erfolgreich zurückgegeben wird.

     

• Solaris 9, 10: Die einzige Möglichkeit besteht darin, rmdir () als übergeordnetes Verzeichnis zu versuchen. ENOTEPTY bedeutet, dass der Cache geleert wird. Beim Versuch, rmdir () zu erstellen, schlägt das aktuelle Verzeichnis mit EINVAL fehl und löscht den Cache nicht.

     

• FreeBSD 6.2: Die einzige Möglichkeit besteht darin, rmdir () entweder das übergeordnete Verzeichnis oder die Datei darunter zu versuchen. Fehler ENOTEPTY, ENOTDIR und EACCES bedeuten, dass der Cache geleert wird, aber ENOENT hat ihn nicht gelöscht. FreeBSD cache negative Einträge nicht, so dass sie nicht geleert werden müssen.

Ссылка

    
Daniel Stutzbach 24.06.2010, 18:12
quelle
1

Das Problem hängt mit der Tatsache zusammen, dass der Python-Prozess in einer eigenen Shell ausgeführt wird. Wenn Sie subprocess.Popen(shell=True) ausführen, erstellen Sie eine neue Shell, die das Problem, das Sie gerade erleben, löst.

Python verursacht dieses Problem nicht. Es ist eine Kombination aus NFS (Dateispeicher) und Verzeichnislisten unter Linux.

    
jathanism 24.06.2010 18:15
quelle

Tags und Links