Async 동기화 기원 구축, Part 5 AsyncSemaphore
요즘 공부하고 있어요.NET4.5 병렬 작업의 사용에 관하여.'병렬 작업' 은 이전 버전과 유사한 동기화 메커니즘을 보여 주지 않습니다. 이벤트 대기 핸들, 신호량, lock, Reader Writer Lock... 등 동기화 기원 대상을 보여 주지 않지만, 우리는 시내를 따라 프로그래밍 습관을 나타낼 수 있습니다. 그러면 이 일련의 번역은 '병렬 작업' 에 동기화 기원 대상을 봉인하는 것입니다.번역 리소스 Async 및 Await에 대한 FAQ
1. Async 동기화 기원 구축, Part 1 AsyncManualResetEvent
2. Async 동기화 기원 구축, Part 2 AsyncAutoResetEvent
3. Async 동기화 기원 구축, Part 3 AsyncCountdown Event
4. Async 동기화 기원 구축, Part 4 AsyncBarrier
5. Async 동기화 기원 구축, Part 5 AsyncSemaphore
6. Async 동기화 기원 구축, Part 6 AsyncLock
7. Async 동기화 기원 구축, Part 7 AsyncReader WriterLock
원본: Async 동기화 기원을 구축합니다.rar
시작: Async 동기화 기원 구축, Part 5 AsyncSemaphore
이전 글에서 저는 AsyncManualReset Event, AsyncAutoReset Event, AsyncCountdown Event와 AsyncBarrier를 구축했습니다.이 글에서, 나는 AsyncSemaphore 클래스를 구축할 것이다.
Semaphore(신호량)는 널리 사용되고 있습니다.중요한 응용 프로그램 중 하나는 접근 제한 자원을 보호하기 위한 것이다.에 있습니다.NET에는 두 가지 신호량 유형이 있는데 그것이 바로 Semaphore(Win32 함수 봉인)와 Semaphore Slim(봉인 모니터가 실현한 경량판)이다.이제 간단한 Async 버전을 구축할 예정입니다. 구축할 대상 유형은 다음과 같습니다.
public class AsyncSemaphore
{
public AsyncSemaphore(int initialCount);
public Task WaitAsync();
public void Release();
}
우리는 AsyncAutoResetEvent 구성원과 거의 같은 구성원 변수가 필요합니다. 변수가 존재하는 역할도 유사합니다.단일 대기자를 깨울 수 있어야 하기 때문에TaskCompletionSource의 실례 대기열을 유지합니다.우리는 막히기 전에 얼마나 많은 대기자가 완성할 수 있는지 알 수 있도록 신호량의 현재 계수를 추적해야 한다.그리고 우리는 이미 완성된 Task를 다시 사용하기 위해 유지하는 효율적인 조치를 발견할 수 있습니다.
private readonly static Task s_completed = Task.FromResult(true);
private readonly Queue>m_waiters
= new Queue>();
private int m_currentCount;
클래스의 구조 함수는 초기화 요청 계수일 뿐입니다.
public AsyncSemaphore(int initialCount)
{
if (initialCount< 0)
throw new ArgumentOutOfRangeException("initialCount");
m_currentCount = initialCount;
}
이제 Waitasync () 방법을 구축해 보겠습니다.이 방법에서 우리는 lock을 사용하여 모든 작업이 원자로 실행되고 Release () 방법과 동기화되는지 확인해야 한다.그리고 여기에는 두 가지 상황이 있다.현재 mcurrentCount은 0보다 크고semaphore 제한 한계에 도달하지 않았기 때문에 이 대기 작업은 즉시 완성될 수 있습니다.이러한 상황에서 우리는 현재 계수를 줄이고 캐시에서 이미 완성한 퀘스트s 를 되돌려줍니다completed (즉, 논쟁이 없는 상황에서 우리는 새로운TaskCompletionSource 실례를 만들 필요가 없습니다.)현재 카운트 mcurrentCount는 0입니다. 우리는 새로운TaskCompletionSource 실례를 대기열에 추가하고 실례에 대응하는Task를 호출자에게 되돌려줍니다.
public Task WaitAsync()
{
lock (m_waiters)
{
if (m_currentCount > 0)
{
--m_currentCount;
return s_completed;
}
else
{
var waiter = new TaskCompletionSource();
m_waiters.Enqueue(waiter);
return waiter.Task;
}
}
}
Release () 방법에서 대기열에 대기자가 있으면 대기열에서 대기자를 삭제하고 해당하는 TaskCompletionSource 실례를 완성합니다.대기자가 없으면 현재 계수 m 를 간단하게 증가합니다currentCount.여기서는 원자성을 유지하고 Waitasync () 방법과 동기화해야 하기 때문에 Release () 의 주체 코드는 다시 mwaiters 대기열에 자물쇠를 채웁니다.여기서 주의해야 할 중요한 것은 앞의 글에서TaskCompletionSource의 [Try]Set*() 시리즈 방법을 토론했고TaskCompletionSource에 대응하는Task를 동기화 호출의 일부로 운행할 수 있도록 했다.만약 우리가 lock 내부에서 SetResilt () 를 호출한다면, Task의 동기화가 계속되는 운행은 장시간 lock을 가지고 있을 것입니다.따라서 lock을 해제한 후 Task의 [Try] Set* () 시리즈 방법을 사용하여 작업을 완료합니다.
public void Release()
{
TaskCompletionSource toRelease = null;
lock (m_waiters)
{
if (m_waiters.Count > 0)
toRelease = m_waiters.Dequeue();
else
++m_currentCount;
}
if (toRelease != null)
toRelease.SetResult(true);
}
이것이 바로 이 절에서 말하고자 하는 AsyncSemaphore이다.
전체 소스는 다음과 같습니다.
public class AsyncSemaphore
{
// Task
private readonly static Task s_completed = Task.FromResult(true);
private readonly Queue> m_waiters
= new Queue>();
// ,
private int m_currentCount;
public AsyncSemaphore(int initialCount)
{
if (initialCount < 0)
throw new ArgumentOutOfRangeException("initialCount");
m_currentCount = initialCount;
}
public Task WaitAsync()
{
lock (m_waiters)
{
if (m_currentCount > 0)
{
--m_currentCount;
return s_completed;
}
else
{
var waiter = new TaskCompletionSource();
m_waiters.Enqueue(waiter);
return waiter.Task;
}
}
}
public void Release()
{
TaskCompletionSource toRelease = null;
lock (m_waiters)
{
if (m_waiters.Count > 0)
toRelease = m_waiters.Dequeue();
else
++m_currentCount;
}
if (toRelease != null)
toRelease.SetResult(true);
}
}
다음 절에서는 AsyncSemaphore를 사용하여 하나의 작용역 상호 배척 잠금 메커니즘을 실현하는 방법을 볼 것이다.
권장 읽기:
비동기 프로그래밍: 동기화 기원 대상 (위)
비동기 프로그래밍: 동기화 기원 대상 (하)
시청해 주셔서 감사합니다..
원문: Building Async Coordination Primitives, Part 5: AsyncSemaphore
작성자: Stephen Toub – MSFT
이 내용에 흥미가 있습니까?
현재 기사가 여러분의 문제를 해결하지 못하는 경우 AI 엔진은 머신러닝 분석(스마트 모델이 방금 만들어져 부정확한 경우가 있을 수 있음)을 통해 가장 유사한 기사를 추천합니다:
다양한 언어의 JSONJSON은 Javascript 표기법을 사용하여 데이터 구조를 레이아웃하는 데이터 형식입니다. 그러나 Javascript가 코드에서 이러한 구조를 나타낼 수 있는 유일한 언어는 아닙니다. 저는 일반적으로 '객체'{}...
텍스트를 자유롭게 공유하거나 복사할 수 있습니다.하지만 이 문서의 URL은 참조 URL로 남겨 두십시오.
CC BY-SA 2.5, CC BY-SA 3.0 및 CC BY-SA 4.0에 따라 라이센스가 부여됩니다.