【问题标题】:when CreateDirectory returns ERROR_ACCESS_DENIED and "shouldn't"当 CreateDirectory 返回 ERROR_ACCESS_DENIED 并且“不应该”时
【发布时间】:2010-08-21 03:59:54
【问题描述】:

我的 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] 因为我真的不知道发生了什么,所以可能无法自信地确定一个合理的时间来继续尝试。

有人有这方面的经验吗?有什么建议吗?在这一点上特别有价值的是有关导致此问题的原因的线索,以便我可以更轻松地重现该问题。

【问题讨论】:

    标签: winapi directory tmp getlasterror


    【解决方案1】:

    你说得对。 documentation 甚至没有将 ERROR_ACCESS_DENIED 列为该函数的可能错误代码,因此它很可能是一个错误。

    我会按照你的建议实施重试/退避策略。

    换句话说,如果您收到该错误,则最多再试 3 次,没有延迟(如果您收到一个非错误返回码,显然会在此处停止),然后最多再试 4 次,延迟为 (例如,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
    

    【讨论】:

    • 这似乎在测试场景中工作得相当好。但是,我似乎无法再在我的真实程序中重现这个问题。知道是什么原因造成的吗?
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2019-08-30
    • 2011-08-14
    • 2018-12-25
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多