Rumah > pembangunan bahagian belakang > C++ > Bagaimana untuk Melaksanakan Penguncian Asynchronous Dengan Betul Menggunakan SemaphoreSlim untuk Mencegah Ralat Akses Fail Selang-seli?

Bagaimana untuk Melaksanakan Penguncian Asynchronous Dengan Betul Menggunakan SemaphoreSlim untuk Mencegah Ralat Akses Fail Selang-seli?

Barbara Streisand
Lepaskan: 2025-01-15 09:49:50
asal
889 orang telah melayarinya

How to Correctly Implement Asynchronous Locking Using SemaphoreSlim to Prevent Intermittent File Access Errors?

Mengatasi Ralat Akses Fail Selang-seli dengan Penguncian Asynchronous

Pustaka ImageProcessor baru-baru ini mengalami ralat akses fail terputus-putus semasa kemas kini cache, berpunca daripada penguncian tak segerak yang cacat. Artikel ini menganalisis pelaksanaan asal yang rosak dan menyediakan penyelesaian yang mantap.

Pendekatan asal menggunakan URL cincang sebagai kunci untuk kunci tak segerak, menyimpan SemaphoreSlim kejadian dalam ConcurrentDictionary untuk memastikan penguncian satu kekunci. Kelemahan kritikal terletak pada mengalih keluar SemaphoreSlim secara serentak daripada kamus sebelum mengeluarkan semaphore. Keadaan perlumbaan ini menyebabkan konflik akses fail.

Coretan kod berikut menggambarkan kunci bermasalah/SemaphoreSlim merujuk:

<code class="language-csharp">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;
}</code>
Salin selepas log masuk

Di bawah ialah kelas AsyncDuplicateLock yang diperbetulkan, menyelesaikan isu konkurensi:

<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>
Salin selepas log masuk

Pelaksanaan yang disemak ini memastikan semaphore dikeluarkan sebelum dialih keluar daripada kamus, menghapuskan keadaan perlumbaan dan menyelesaikan ralat akses fail yang terputus-putus.

Atas ialah kandungan terperinci Bagaimana untuk Melaksanakan Penguncian Asynchronous Dengan Betul Menggunakan SemaphoreSlim untuk Mencegah Ralat Akses Fail Selang-seli?. Untuk maklumat lanjut, sila ikut artikel berkaitan lain di laman web China PHP!

sumber:php.cn
Kenyataan Laman Web ini
Kandungan artikel ini disumbangkan secara sukarela oleh netizen, dan hak cipta adalah milik pengarang asal. Laman web ini tidak memikul tanggungjawab undang-undang yang sepadan. Jika anda menemui sebarang kandungan yang disyaki plagiarisme atau pelanggaran, sila hubungi admin@php.cn
Artikel terbaru oleh pengarang
Tutorial Popular
Lagi>
Muat turun terkini
Lagi>
kesan web
Kod sumber laman web
Bahan laman web
Templat hujung hadapan