2

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

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

4

1 回答 1

1

你是对的。该文档甚至没有将 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
于 2010-08-21T04:15:10.817 回答