当CreateDirectory返回ERROR_ACCESS_DENIED并且“不应该”

时间:2010-08-21 03:59:55

标签: winapi directory tmp getlasterror

我的Win32应用程序A1(实际上是一组进程)正在尝试使用CreateDirectory在父目录P中创建目录D1.P的路径是TMP环境变量的值,这使得P成为一个潜在的繁忙但通常是宽容的地方。在绝大多数情况下,一切正常,但很少,CreateDirectory失败,GetLastError然后返回ERROR_ACCESS_DENIED,在此上下文中的含义未记录。

我写了一个测试应用程序A2,除了在P内尽可能快地重复创建和删除目录D2之外什么也没做,我为D2选择了一个愚蠢的长名称,我有信心不会碰到任何其他任何程序会用。每隔几分钟,有一小部分时间,A2尝试创建D2只会产生ERROR_ACCESS_DENIED次失败。

A1在运行期间在P内非常繁忙。当A1和A2同时运行时,ERROR_ACCESS_DENIED故障的周期会更频繁地发生,就像A1和A2竞争P的独占访问一样(我绝对确定A1不使用与D2相同的名称) 。: - )

我有点倾向于将ERROR_ACCESS_DENIED表示“在几毫秒内再试一次,如果在几次尝试之后不起作用,就放弃”,但我担心[a]在某些情况下,它可能意味着我应该立即注意的永久性事件,[b]因为我真的不知道发生了什么,所以可能无法自信地确定合理的时间来继续尝试。

有人有这方面的经验吗?有什么建议?在这一点上特别有价值的是关于是什么导致这一点的线索,所以我可以更容易地重现问题。

1 个答案:

答案 0 :(得分: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
相关问题