J'ai plusieurs threads fonctionnant en parallèle depuis Python sur un système de cluster. Chaque thread python sort dans un répertoire mydir
. Chaque script, avant la sortie vérifie si mydir existe et sinon le crée:
if not os.path.isdir(mydir):
os.makedirs(mydir)
mais cela donne l'erreur:
os.makedirs(self.log_dir)
File "/usr/lib/python2.6/os.py", line 157, in makedirs
mkdir(name,mode)
OSError: [Errno 17] File exists
Je soupçonne que cela pourrait être dû à une condition de concurrence, où un travail crée le dir avant que l'autre n'y arrive. Est-ce possible? Si oui, comment éviter cette erreur?
Je ne suis pas sûr que ce soit une condition de concurrence, alors je me demandais si d'autres problèmes dans Python peuvent provoquer cette étrange erreur.
Tout code temporel peut s'exécuter entre le moment où vous vérifiez quelque chose et le moment où vous agissez dessus, vous aurez une condition de concurrence. Une façon d'éviter cela (et la manière habituelle en Python) est d'essayer puis de gérer l'exception
while True:
mydir = next_dir_name()
try:
os.makedirs(mydir)
break
except OSError, e:
if e.errno != os.errno.EEXIST:
raise
# time.sleep might help here
pass
Si vous avez beaucoup de threads essayant de créer une série prévisible de répertoires, cela soulèvera toujours de nombreuses exceptions, mais vous y arriverez à la fin. Mieux vaut avoir un seul thread créant les répertoires dans ce cas
À partir de Python >=3.2
, os.makedirs()
peut prendre un troisième argument optionnel exist_ok
:
os.makedirs(mydir, exist_ok=True)
Attrapez l'exception et, si le numéro d'erreur est 17, ignorez-le. C'est la seule chose que vous pouvez faire s'il y a une condition de concurrence entre les appels isdir
et makedirs
.
Cependant, il pourrait également être possible qu'un fichier avec le même nom existe - dans ce cas os.path.exists
renverrait True
mais os.path.isdir
renvoie faux.
J'ai eu des problèmes similaires et voici ce que j'ai fait
try:
if not os.path.exists(os.path.dirname(mydir)):
os.makedirs(os.path.dirname(mydir))
except OSError as err:
print(err)
Description: Le simple fait de vérifier si le répertoire existe déjà génère ce message d'erreur [Errno 17] Le fichier existe car nous vérifions simplement si le nom de répertoire existe ou non qui renverra le nom de répertoire de la valeur mydir passée mais pas si elle existe déjà ou non. Ce qui manque, ce n'est pas de vérifier si ce répertoire existe déjà, ce qui peut être fait en vérifiant le chemin avec os.path.exists () et là nous avons passé le nom du répertoire respectif.
Pour ignorer l'erreur d'existence du répertoire ou du fichier, vous pouvez essayer ceci:
except OSError, e:
if e.errno != 17:
print("Error:", e)