Heim > Backend-Entwicklung > C++ > Wie behebt man zeitweise auftretende Dateizugriffsfehler beim asynchronen Sperren?

Wie behebt man zeitweise auftretende Dateizugriffsfehler beim asynchronen Sperren?

Barbara Streisand
Freigeben: 2025-01-15 07:14:44
Original
956 Leute haben es durchsucht

How to Solve Intermittent File Access Errors in Asynchronous Locking?

Schlüsselbasiertes asynchrones Sperren

In diesem Artikel wird ein Problem besprochen, das in der ImageProcessor-Bibliothek aufgetreten ist: ein zeitweiliger Dateizugriffsfehler beim Hinzufügen des Caches. Die Fehlermeldung weist darauf hin, dass die betreffende Datei von einem anderen Prozess verwendet wird. Um dieses Problem zu lösen, wird ein schlüsselbasierter asynchroner Sperrmechanismus implementiert. Später stellte sich jedoch heraus, dass bei dieser Implementierung ein Versehen vorlag.

Das Problem

Die ursprüngliche Sperrklasse AsyncDuplicateLock versucht, eine asynchrone Sperrung durchzuführen, indem sie das Semaphor mithilfe des Schlüssels aus dem gleichzeitigen Wörterbuch abruft. Es wird jedoch versehentlich das Semaphor aus dem Wörterbuch entfernt, bevor es freigegeben wird. Dies bedeutet, dass das Semaphor gelöscht wurde, während es noch verwendet wurde, was zu dem beobachteten Dateizugriffsfehler führte.

Lösung

Um dieses Problem zu lösen, wurde die Sperrklasse geändert. Anstatt einen gleichzeitigen, wörterbuchbasierten, sperrenfreien Ansatz zu verwenden, verwendet die aktualisierte Version einen traditionelleren Ansatz, der Referenzzählung und eine einzelne Sperre kombiniert. Dadurch wird sichergestellt, dass Semaphore erst dann freigegeben werden, wenn sie nicht mehr verwendet werden.

Das Folgende ist der geänderte Sperrklassencode:

<code class="language-csharp">public sealed class AsyncDuplicateLock
{
    private sealed class RefCounted<T>
    {
        public RefCounted(T value)
        {
            RefCount = 1;
            Value = value;
        }

        public int RefCount { get; set; }
        public T Value { get; private set; }
    }

    private static readonly Dictionary<object, RefCounted<SemaphoreSlim>> SemaphoreSlims
                        = new Dictionary<object, RefCounted<SemaphoreSlim>>();

    private SemaphoreSlim GetOrCreate(object key)
    {
        RefCounted<SemaphoreSlim> item;
        lock (SemaphoreSlims)
        {
            if (SemaphoreSlims.TryGetValue(key, out item))
            {
                ++item.RefCount;
            }
            else
            {
                item = new RefCounted<SemaphoreSlim>(new SemaphoreSlim(1, 1));
                SemaphoreSlims[key] = item;
            }
        }
        return item.Value;
    }

    public IDisposable Lock(object key)
    {
        GetOrCreate(key).Wait();
        return new Releaser { Key = key };
    }

    public async Task<IDisposable> LockAsync(object key)
    {
        await GetOrCreate(key).WaitAsync().ConfigureAwait(false);
        return new Releaser { Key = key };
    }

    private sealed class Releaser : IDisposable
    {
        public object Key { get; set; }

        public void Dispose()
        {
            RefCounted<SemaphoreSlim> item;
            lock (SemaphoreSlims)
            {
                item = SemaphoreSlims[Key];
                --item.RefCount;
                if (item.RefCount == 0)
                    SemaphoreSlims.Remove(Key);
            }
            item.Value.Release();
        }
    }
}</code>
Nach dem Login kopieren

Diese aktualisierte Implementierung verwaltet einen Referenzzähler für jedes Semaphor und stellt sicher, dass das Semaphor nur dann aus dem Wörterbuch entfernt wird, wenn keine weiteren aktiven Sperren mehr darauf verweisen. Dieser Ansatz behebt effektiv zeitweise auftretende Dateizugriffsfehler, die in früheren Implementierungen aufgetreten sind.

Das obige ist der detaillierte Inhalt vonWie behebt man zeitweise auftretende Dateizugriffsfehler beim asynchronen Sperren?. Für weitere Informationen folgen Sie bitte anderen verwandten Artikeln auf der PHP chinesischen Website!

Quelle:php.cn
Erklärung dieser Website
Der Inhalt dieses Artikels wird freiwillig von Internetnutzern beigesteuert und das Urheberrecht liegt beim ursprünglichen Autor. Diese Website übernimmt keine entsprechende rechtliche Verantwortung. Wenn Sie Inhalte finden, bei denen der Verdacht eines Plagiats oder einer Rechtsverletzung besteht, wenden Sie sich bitte an admin@php.cn
Neueste Artikel des Autors
Beliebte Tutorials
Mehr>
Neueste Downloads
Mehr>
Web-Effekte
Quellcode der Website
Website-Materialien
Frontend-Vorlage