Rumah > pembangunan bahagian belakang > C++ > Bagaimana untuk Menyelesaikan Ralat Akses Fail Berselang-seli dalam Penguncian Asynchronous?

Bagaimana untuk Menyelesaikan Ralat Akses Fail Berselang-seli dalam Penguncian Asynchronous?

Barbara Streisand
Lepaskan: 2025-01-15 07:14:44
asal
956 orang telah melayarinya

How to Solve Intermittent File Access Errors in Asynchronous Locking?

Penguncian tak segerak berasaskan kunci

Artikel ini membincangkan isu yang dihadapi dalam pustaka ImageProcessor: ralat akses fail terputus-putus semasa penambahan cache. Mesej ralat menunjukkan bahawa fail berkenaan sedang digunakan oleh proses lain. Untuk menyelesaikan masalah ini, mekanisme penguncian tak segerak berasaskan kunci dilaksanakan. Walau bagaimanapun, ia kemudiannya mendapati bahawa pelaksanaan ini mempunyai kesilapan.

Masalahnya

Kelas penguncian asal AsyncDuplicateLock cuba melakukan penguncian tak segerak dengan mendapatkan semula semafor daripada kamus serentak menggunakan kekunci. Walau bagaimanapun, ia tersilap mengalih keluar semafor daripada kamus sebelum mengeluarkannya. Ini bermakna bahawa semaphore telah dipadamkan semasa masih digunakan, membawa kepada ralat capaian fail yang diperhatikan.

Penyelesaian

Untuk menyelesaikan masalah ini, kelas penguncian telah diubah suai. Daripada menggunakan pendekatan tanpa kunci berasaskan kamus serentak, versi yang dikemas kini menggunakan pendekatan yang lebih tradisional yang menggabungkan pengiraan rujukan dan satu kunci. Ini memastikan bahawa semaphore hanya dikeluarkan apabila ia tidak lagi digunakan.

Berikut ialah kod kelas kunci yang diubah suai:

<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 dikemas kini ini mengekalkan kiraan rujukan untuk setiap semaphore dan memastikan semaphore hanya dialih keluar daripada kamus apabila tiada lagi kunci aktif merujuk kepadanya. Pendekatan ini berkesan menyelesaikan ralat akses fail terputus-putus yang dihadapi dalam pelaksanaan sebelumnya.

Atas ialah kandungan terperinci Bagaimana untuk Menyelesaikan Ralat Akses Fail Berselang-seli dalam Penguncian Asynchronous?. 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