2010-08-21 18 views
2

Mon application Win32 A1 (en réalité une collection de processus) essaie d'utiliser CreateDirectory pour créer un répertoire D1 dans le répertoire parent P. Le chemin vers P est la valeur de l'environnement TMP variable, ce qui fait de P un lieu potentiellement occupé mais généralement permissif. La grande majorité du temps, tout fonctionne bien, mais, rarement, CreateDirectory échoue et GetLastError renvoie alors ERROR_ACCESS_DENIED, dont la signification dans ce contexte n'est pas documentée. J'ai écrit une application de test A2 qui ne fait que créer et supprimer à plusieurs reprises un répertoire D2 aussi rapidement que possible dans P, et j'ai choisi un nom long et maladroit pour D2 qui, j'en suis persuadé, n'entre pas en collision avec autre programme utiliserait. Une fois toutes les quelques minutes, il y a une petite fraction de seconde au cours de laquelle les tentatives de A2 pour créer D2 ne produisent que des échecs ERROR_ACCESS_DENIED.lorsque CreateDirectory renvoie ERROR_ACCESS_DENIED et "ne devrait pas"

A1 devient très occupé dans P pendant son exécution. Alors que A1 et A2 tournent simultanément, les périodes d'échec ERROR_ACCESS_DENIED se produisent un peu plus fréquemment, comme si A1 et A2 sont en concurrence pour un accès exclusif à P. (Je suis absolument certain que A1 n'utilise pas le même nom que D2.)

Je suis un peu enclin à prendre ERROR_ACCESS_DENIED pour signifier "essayer à nouveau dans quelques millisecondes, et si cela ne fonctionne pas après quelques essais, abandonner", mais je suis inquiet que [a] dans certains cas cela peut signifier quelque chose de permanent dont je devrais tenir compte tout de suite, et [b] parce que je ne sais pas vraiment ce qui se passe, il ne sera peut-être pas possible d'établir en toute confiance un délai raisonnable pour continuer à essayer.

Quelqu'un a-t-il de l'expérience? Aucun conseil? Une valeur particulière à ce stade serait des indices sur ce qui cause cela afin que je puisse reproduire le problème plus facilement.

Répondre

1

Vous avez tout à fait raison. Le documentation n'indique même pas ERROR_ACCESS_DENIED comme un code d'erreur possible pour cette fonction, donc cela pourrait bien être un bug. Je ferais comme vous le suggérez dans la mise en œuvre d'une stratégie de relance/backoff. En d'autres termes, si vous obtenez cette erreur, réessayez jusqu'à trois fois sans délai (arrêtez-vous évidemment ici si vous obtenez un code retour sans erreur), puis jusqu'à quatre autres fois avec des retards de (par exemple, 100 millisecondes, 500 millisecondes, 1 seconde et 2 secondes).

Ce type de stratégie (que j'ai utilisé auparavant) contourne généralement toute pénurie temporaire de ressources. Si vous ne pouvez toujours pas créer le répertoire après 7 tentatives et 3.6 + secondes, vous pouvez probablement supposer que cela ne se produira pas.

Votre fonction pourrait être aussi laid que (pseudo-code):

def createMyDir (dirname): 
    if createDir (dirName) return true; 
    if createDir (dirName) return true; 
    if createDir (dirName) return true; 
    sleep (100) 
    if createDir (dirName) return true; 
    sleep (500) 
    if createDir (dirName) return true; 
    sleep (1000) 
    if createDir (dirName) return true; 
    sleep (2000) 
    return createDir (dirName); 

mais vous pouvez vous rendre un peu plus élégant:

def createMyDir (dirname): 
    delay = pointer to array [0, 0, 0, 100, 500, 1000, 2000, -1] 
    okay = createDir (dirName) 
    while not okay and [delay] not -1: 
     if [delay] not 0: 
      sleep ([delay]) 
     delay = next delay 
     okay = createDir (dirName) 
    return okay 
+0

Cela semble fonctionner assez bien dans un scénario de test. Cependant, il semble que je ne puisse plus reproduire ce problème dans mon vrai programme. Une idée de ce qui le cause? –