> 백엔드 개발 > C++ > 비동기 잠금에서 간헐적인 파일 액세스 오류를 해결하는 방법은 무엇입니까?

비동기 잠금에서 간헐적인 파일 액세스 오류를 해결하는 방법은 무엇입니까?

Barbara Streisand
풀어 주다: 2025-01-15 07:14:44
원래의
956명이 탐색했습니다.

How to Solve Intermittent File Access Errors in Asynchronous Locking?

키 기반 비동기 잠금

이 문서에서는 ImageProcessor 라이브러리에서 발생하는 문제인 캐시 추가 중 간헐적인 파일 액세스 오류에 대해 설명합니다. 오류 메시지는 문제의 파일이 다른 프로세스에서 사용되고 있음을 나타냅니다. 이 문제를 해결하기 위해 키 기반 비동기 잠금 메커니즘이 구현되었습니다. 그러나 나중에 이 구현에 실수가 있었음이 밝혀졌습니다.

문제

원래 잠금 클래스AsyncDuplicateLock는 키를 사용하여 동시 사전에서 세마포어를 검색하여 비동기 잠금을 수행하려고 시도합니다. 그러나 이를 해제하기 전에 실수로 사전에서 세마포어를 제거합니다. 이는 아직 사용 중인 동안 세마포어가 삭제되어 관찰된 파일 액세스 오류가 발생했음을 의미합니다.

솔루션

이 문제를 해결하기 위해 잠금 클래스를 수정했습니다. 동시 사전 기반 잠금 없는 접근 방식을 사용하는 대신 업데이트된 버전은 참조 계산과 단일 잠금을 결합하는 보다 전통적인 접근 방식을 사용합니다. 이렇게 하면 세마포어가 더 이상 사용되지 않을 때만 해제됩니다.

수정된 잠금 클래스 코드는 다음과 같습니다.

<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>
로그인 후 복사

이 업데이트된 구현은 각 세마포어에 대한 참조 카운트를 유지하고 더 이상 활성 잠금이 참조하지 않는 경우에만 세마포어가 사전에서 제거되도록 보장합니다. 이 접근 방식은 이전 구현에서 발생한 간헐적인 파일 액세스 오류를 효과적으로 해결합니다.

위 내용은 비동기 잠금에서 간헐적인 파일 액세스 오류를 해결하는 방법은 무엇입니까?의 상세 내용입니다. 자세한 내용은 PHP 중국어 웹사이트의 기타 관련 기사를 참조하세요!

원천:php.cn
본 웹사이트의 성명
본 글의 내용은 네티즌들의 자발적인 기여로 작성되었으며, 저작권은 원저작자에게 있습니다. 본 사이트는 이에 상응하는 법적 책임을 지지 않습니다. 표절이나 침해가 의심되는 콘텐츠를 발견한 경우 admin@php.cn으로 문의하세요.
저자별 최신 기사
인기 튜토리얼
더>
최신 다운로드
더>
웹 효과
웹사이트 소스 코드
웹사이트 자료
프론트엔드 템플릿