제5 장 데이터 구조 조정 노트

10792 단어 데이터 구조
이 장 에 서 는 경량급 동기 화 원 어 를 소개 하 였 으 며, 그 중 상당 부분 은. NET Framework 4 에서 도입 되 었 다.
System.Threading.Barrier
한 단계 의 프로그램 을 여러 단계 로 나 누 는 데 사용 되 며, 모든 단계 의 시작 은 이전의 단계 가 완성 되 어야 한다.이 프로그램 이 병행 화 되 어야 한다 면.단락 마다 Barrier 를 사용 할 수 있 습 니 다.
단계 마다 동작 을 설정 할 수 있 습 니 다.
task 는 Barrier 에서 참여 자 (participant) 가 되 고 구조 할 때 수량 을 설정 해 야 하 며 동적 으로 삭제 할 수도 있다.
이상 과 시간 초과 처 리 는 코드 를 참고 할 수 있 습 니 다.
Barrier 는 Task 를 사용 하 는 Continue With 방법 으로 여러 단계 의 직렬 을 실현 하 는 것 보다 Task 수 를 매우 많이 줄 일 수 있다.
사용 후 Dispose 가 필요 합 니 다.
Task[] _tasks;
Barrier _barrier;
 
_tasks
=
new Task[
4];
_barrier
=
new Barrier(
4, (barrier)
=
>
{
    Console.WriteLine(
"Current phase: {0}",
        barrier.CurrentPhaseNumber);
});
 
for (
int i
=
0; i
<
4; i
++)
{
    _tasks[i]
= Task.Factory.StartNew((num)
=
>
    {
        
단계 1
        
if (
!_barrier.SignalAndWait(TIMEOUT))
        {
            
//...
        }
        
단계 2
        
try
        {
            _barrier.SignalAndWait();
        }
        
catch (BarrierPostPhaseException bppex)
        {
            
//..
            
break;
        }
        
단계 3
        _barrier.SignalAndWait();
    }, i);
}
상호 배척 자물쇠
C \ # lock 키 워드 를 제공 하여 상호 배척 자 물 쇠 를 가 져 옵 니 다. lock 블록 을 컴 파일 할 때 대 체 됩 니 다.
System. Threading. Monitor 사용.
주의해 야 할 점 이 있어 요.

  • lock 과 Monitor 는 참조 형식의 인 스 턴 스 만 잠 글 수 있 으 며, 값 형식 에 lock 이나 Monitor 를 사용 하지 마 십시오.

  • 나 를 잠 그 는 것 을 피하 고 구성원 이나 클래스 의 경 계 를 뛰 어 넘 거나 자 물 쇠 를 풀 지 않도록 해 야 합 니 다.

  • 임계 구역 의 코드 는 가능 한 한 간단하게 유지 해 야 한다.

  • lock (_obj)
    {
        
    //...
    }
    / / 컴 파일 시 lock 블록 은 다음 과 같이 대 체 됩 니 다.
    bool lockTaken
    =
    false;
    Monitor.Enter(_obj,
    ref lockTaken);
    try
    {
        
    //...
    }
    finally
    {
        
    if (lockTaken)
        {
            Monitor.Exit(_obj);
        }
    }
    Monitor 를 직접 사용 하면 TryEnter 를 사용 해서 시간 초과 설정 을 할 수도 있어 요.
    bool lockTaken
    =
    false;
    try
    {
        Monitor.TryEnter(_obj,
    2000,
    ref lockTaken);
        
    if (
    !lockTaken)
        {
            
    throw
    new TimeoutException(...);
        }
        
    //...
    }
    finally
    {
        
    if (lockTaken)
        {
            Monitor.Exit(_obj);
        }
    }
    자전
    Monitor 는 비용 이 많이 듭 니 다. 잠 금 시간 이 매우 짧 으 면 자 회전 잠 금 이 더 좋 은 성능 을 얻 을 수 있 습 니 다.
    하지만 장시간 자전 하면 SpinWait 는 시간 영 화 를 내 주 며 컨 텍스트 전환 을 촉발 합 니 다. 바 쁜 것 과 는 다 릅 니 다.
    만약 여러 임무 가 자전 자물쇠 가 필요 하 다 면, 모든 임 무 는 자신의 실례 를 사용 해 야 한다
    SpinWait 는 단일 핵 에서 실제 적 인 의미 가 없습니다. 반드시 문맥 전환 을 해 야 기다 릴 수 있 기 때 문 입 니 다.
    SpinWait. SpinUntil (Func < bool > condition, int milliseconds Timeout) 은 자전 적 인 등 대기 방안 을 제공 합 니 다.
    var sl
    =
    new SpinLock(
    false);
    bool lockTaken
    =
    false;
    try
    {
        sl.TryEnter(
    2000,
    ref lockTaken);
        
    if (
    !lockTaken)
        {
            
    throw
    new TimeoutException(...);
        }
        
    //....
    }
    finally
    {
        
    if (lockTaken)
        {
            sl.Exit(
    false);
        }
    }  

    System.Threading.ManualResetEventSlim

    ManualResetEventSlim ManualResetEvent 。 AppDomain。
    ManualResetEventSlim , (true) (false)
    Dispose。
    private ManualResetEventSlim manualResetEvent1;
    private ManualResetEventSlim manualResetEvent2;
    //method1
    try
    {
        manualResetEvent1.Set();
         //..
    }
    finally
    {
        manualResetEvent1.Reset();
    }
    //method2
    try
    {
        manualResetEvent2.Set();
         if ( !manualResetEvent1.Wait(TIMEOUT))
        {
             throw new TimeoutException(...);
        }
         //...
    }
    finally
    {
         // Switch to unsignaled/unset
        manualResetEvent2.Reset();
    }

    System.Threading.SemaphoreSlim

    System.Threading.Semaphore 。 AppDomain。
    Dispose。
    SemaphoreSlim _semaphore;
     
    _semaphore.Wait();
    try
    {
         //...
    }
    finally
    {
        _semaphore.Release();
    }
     

    System.Threading.CountdownEvent

    CountdownEvent , , 。 Wait 0。
    Dispose

    private static CountdownEvent _countdown;
     
    //Main thread
    _countdown = new CountdownEvent(MIN_PATHS);
    //...
    try
    {
         //new Task
         //...
    }
    finally
    {
        _countdown.Dispose();
    }
     
     
    //Task1
    try
    {
         //...
    }
    finally
    {
        _countdown.Signal();
    }
     
    //Task2
    _countdown.Wait();
    //...
     

    , 。
    System.Threading.Interlocked, 。
    int total = 0;
    Interlocked.Increment( ref total);
    , 32 。 64 。 Interlocked.Read(ref long location)。64 , 。





    좋은 웹페이지 즐겨찾기