os.path.exists () лежит - PullRequest
       16

os.path.exists () лежит

9 голосов
/ 24 июня 2010

Я запускаю несколько сценариев Python в кластере Linux, и выходные данные одного задания обычно являются входными данными для другого сценария, который может выполняться на другом узле. Я обнаружил, что до того, как python замечает файлы, которые были созданы на других узлах, существует некоторое незначительное отставание - os.path.exists () возвращает false, а open () также завершается неудачно. Я могу делать цикл os.path.exists (mypath) некоторое время, пока файл не появится, и это может занять до полной минуты, что не является оптимальным в конвейере с большим количеством шагов и потенциально может выполнять множество наборов данных параллельно. *

Единственный найденный мной обходной путь - это вызов subprocess.Popen ("ls% s"% (pathdir), shell = True), который волшебным образом решает проблему. Я полагаю, что это, вероятно, системная проблема, но каким-либо образом Python может быть причиной этого? Какой-то кеш или что-то? Мой сисадмин не очень помог.

Ответы [ 2 ]

10 голосов
/ 24 июня 2010

os.path.exists() просто вызывает функцию библиотеки C stat().

Я полагаю, что вы используете кеш в реализации ядра NFS.Ниже приведена ссылка на страницу, описывающую проблему, а также некоторые методы очистки кэша.

Кэширование дескриптора файла

Каталоги имен файлов кэша для сопоставления дескрипторов файлов,Наиболее распространенные проблемы с этим:

• У вас есть открытый файл, и вам нужно проверить, был ли файл заменен более новым файлом.Вы должны очистить кэш дескриптора файла родительского каталога, прежде чем stat () вернет информацию о новом файле, а не информацию об открытом файле.

ct На самом деле в этом случае есть еще одна проблема: старый файл мог быть удален и заменен новым, но оба файла могут иметь один и тот же индекс.Вы можете проверить этот случай, очистив кэш атрибутов открытого файла и посмотрев, не удастся ли fstat () с ESTALE.

• Вам необходимо проверить, существует ли файл.Например, файл блокировки.Ядро, возможно, кэшировало, что файл не существует, даже если в действительности это существует.Вы должны очистить кэш отрицательного дескриптора файла родительского каталога, чтобы увидеть, существует ли файл на самом деле.

Несколько способов очистки кэша дескриптора файла:

• Если mtime родительского каталога изменилось, кэш дескриптора файла сбрасывается путем очистки его кэша атрибутов.Это должно работать достаточно хорошо, если сервер NFS поддерживает разрешение наносекунд или микросекунд.

• Linux: chown () каталог для его текущего владельца.Кэш дескриптора файла очищается, если вызов успешно завершен.

• Solaris 9, 10: единственный способ - попытаться выполнить rmdir () в родительском каталоге.ENOTEMPTY означает, что кэш очищен.Попытка выполнения rmdir () в текущем каталоге завершается неудачно с помощью EINVAL и не очищает кэш.

• FreeBSD 6.2: единственный способ - попытаться выполнить rmdir () либо в родительском каталоге, либо в файле под ним.Ошибки ENOTEMPTY, ENOTDIR и EACCES означают, что кэш очищен, но ENOENT не очищал его.FreeBSD не кэширует отрицательные записи, поэтому их не нужно очищать.

http://web.archive.org/web/20100912144722/http://www.unixcoding.org/NFSCoding

1 голос
/ 24 июня 2010

Проблема связана с тем, что процесс Python выполняется в своей собственной оболочке.Когда вы запускаете subprocess.Popen(shell=True), вы создаете новую оболочку, которая решает проблему, с которой вы столкнулись.

Python не вызывает эту проблему.Это сочетание того, как NFS (хранилище файлов) и списки каталогов работают в Linux.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...