2

私のWin32アプリA1(実際にはプロセスのコレクション)はCreateDirectory、親ディレクトリP内にディレクトリD1を作成するために使用しようとしています。PへのパスはTMP環境変数の値であり、Pは潜在的にビジーですが、一般的に許容できる場所になります。ほとんどの場合、すべてが正常に機能しますが、CreateDirectory失敗してGetLastErrorから戻ることはめったにERROR_ACCESS_DENIEDありません。このコンテキストでの意味は文書化されていません。

P内で可能な限り高速にディレクトリD2を繰り返し作成および削除するだけのテストアプリケーションA2を作成し、他のプログラムが使用するものと衝突しないと確信しているD2に間抜けな長い名前を選択しました。 。数分に1回、A2がD2を作成しようとすると、ほんの一瞬でERROR_ACCESS_DENIED失敗が発生します。

A1は、実行中にP内で非常にビジーになります。ERROR_ACCESS_DENIEDA1とA2が同時に実行されている間、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 に答える