2010-08-21 3 views
2

My Win32 app A1 (фактически набор процессов) пытается использовать CreateDirectory для создания каталога D1 в родительском каталоге P. Путь к P - это значение среды TMP переменная, что делает P потенциально занятым, но в целом разрешительным местом. В подавляющем большинстве случаев все работает нормально, но редко, CreateDirectory сбой и GetLastError затем возвращает ERROR_ACCESS_DENIED, смысл которого в этом контексте не документирован., когда CreateDirectory возвращает ERROR_ACCESS_DENIED и «не должен»

Я написал тестовое приложение A2, которое не только многократно создает и удаляет каталог D2 так быстро, как может в P, и я выбрал глупое длинное имя для D2, которое, я уверен, не сталкивается с каким-либо другая программа будет использовать. Каждые несколько минут есть небольшая часть секунды, в течение которой попытки A2 создать D2 дают только ERROR_ACCESS_DENIED сбоев.

A1 во время пробега A1 становится занятым внутри P. В то время как A1 и A2 работают одновременно, периоды с ошибкой ERROR_ACCESS_DENIED происходят несколько чаще, как если бы A1 и A2 конкурировали за эксклюзивный доступ к P. (я абсолютно уверен, что A1 не использует то же имя, что и D2. :-)

Я немного склонен принять ERROR_ACCESS_DENIED, чтобы означать «повторите попытку через несколько миллисекунд, и если это не сработает после нескольких попыток, сдайтесь», но я обеспокоен тем, что [a] в некоторых случаях это может означать что-то постоянное, что я должен сразу прислушаться, и [b], потому что я действительно не знаю, что происходит, может быть невозможно уверенно установить разумное количество времени, чтобы продолжать попытки.

У кого-нибудь есть опыт? Любой совет? Особое значение в этот момент было бы ключом к тому, что вызывает это, поэтому я могу легче воспроизвести проблему.

ответ

1

Ты мертв. documentation даже не перечисляет ERROR_ACCESS_DENIED как возможный код ошибки для этой функции, поэтому может быть ошибкой.

Я бы сделал так, как вы предлагаете в реализации стратегии повторного использования/возврата.

Другими словами, если вы получите эту ошибку, повторите попытку до трех раз без задержки (очевидно, остановитесь в любой точке здесь, если вы получите код возврата без ошибок), а затем до четырех раз с задержками (например, 100 миллисекунд, 500 миллисекунд, 1 секунда и 2 секунды).

Этот вид стратегии (который я использовал раньше) обычно обходит любой временной нехваткой ресурсов. Если вы по-прежнему не можете создать каталог после 7 попыток и 3.6 + секунд, вы можете смело предположить, что этого не произойдет.

Ваша функция может быть уродлив, как (псевдо-код):

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); 

но вы можете вы сделать его немного более элегантна:

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

Это, кажется, работает достаточно хорошо в сценарий тестирования. Однако, похоже, я больше не могу воспроизвести эту проблему в своей реальной программе. Любая идея, что его вызывает? –