.NET 동기화 및 비동기 EventWaitHandle

大家讲道理
풀어 주다: 2017-04-11 14:05:40
원래의
2793명이 탐색했습니다.


이전 기사에서 우리는 Mutex와 이 기사의 주인공을 직간접적으로 언급했습니다 WaitHandle에서 상속:

WaitHandle은 동기화를 위한 여러 메서드를 제공합니다. Mutex에 대한 이전 블로그에서는 이미 인스턴스 메서드인 WaitOne()을 언급했습니다. 또한 WaitHandle에는 동기화를 위한 세 가지 다른

정적 메서드가 있습니다. :

스레드 종속성

Mutex는 Monitor와 마찬가지로 스레드 종속성을 가지고 있습니다. 이전에는 Monitor.Enter()/TryEnter()를 통해
    object
  • 잠금을 얻은 스레드만 Pulse()/Wait()를 호출할 수 있습니다. /Exit(); 마찬가지로 Mutex 소유권을 얻은 스레드만 ReleaseMutex() 메서드를 실행할 수 있습니다. 그렇지 않으면 예외가 발생합니다. 이를 스레드 종속성이라고 합니다.

    반대로 EventWaitHandle과 해당 파생 클래스 AutoResetEvent 및 ManualResetEvent는 스레드 독립적입니다. 모든 스레드는 차단된 스레드를 깨우기 위해 EventWaitHandle에 신호를 보낼 수 있습니다.
  • 다음 글에서 언급할 세마포어 역시 스레드 독립적입니다.

이벤트 알림

EventWaitHandle, AutoResetEvent, ManualResetEvent 모두 이름에 "Event"가 있지만 이 Net 자체의 이벤트

메커니즘은 위임자나

이벤트 핸들러 프로시저와 관련이 없습니다. 스레드가 "잠금"을 위해 경쟁해야 하는 이전에 접한 모니터 및 뮤텍스와 비교할 때 스레드를 기다려야 하는 일부 "이벤트"로 이해할 수 있습니다. 스레드는 이러한 이벤트가 "발생"할 때까지 기다리면서 자체적으로 차단됩니다. "이벤트"가 완료되면 차단된 스레드는 신호를 받은 후 계속 작업할 수 있습니다. WaitHandle의 세 가지 정적 메서드 SingnalAndWait()/WailAny()/WaitAll()과 협력하기 위해 EventWaitHandle은 "이벤트"를 완료하고 다시 시작하는 고유한 메서드를 제공합니다.

  1. 중국어 버전이든 영어 버전이든 이 방법은 "하나" 또는 "여러"의 대기 스레드를 "계속/진행"("깨어나기"가 아님)으로 만들 수 있다고 언급됩니다. . 따라서 이 메서드는 "깨우기" 측면에서 Monitor.Pulse() 및 Monitor.PulseAll()과 유사합니다. Pulse()와 유사한 경우와 PulseAll()과 유사한 경우에 대해서는 계속 읽어보세요.

  2. 이 메서드에는 bool 반환 값이 있습니다. 작업이 성공하면 true이고, 그렇지 않으면 false입니다. 그러나 MSDN에서는 실행이 언제 실패할지 알려주지 않습니다. Microsoft MVP에게만 문의할 수 있습니다.

  • bool:Reset(): 이벤트 상태를 신호 없음으로 설정하여 스레드를 차단합니다. 이벤트 상태를 신호 없음으로 설정하여 스레드를 차단합니다. 마찬가지로, "신호를 받지 않음"과 "종료되지 않음"이 동일한 것임을 이해해야 합니다. 또한 여전히 무의미한 반환 값이 있습니다. Reset() 함수는 이벤트를 다시 "진행 중"으로 만드는 것과 같습니다. 그러면 WaitOne()/WaitAll()/WaitAny()/SignalAndWait() 이벤트의 모든 스레드가 다시 차단됩니다.

  • 생성자

    가장 일반적인 생성자를 살펴보겠습니다. EventWaitHandle 간단한 것:

    • EventWaitHandle(BooleaninitialState, EventResetMode mode): EventWaitHandle 클래스의 새 인스턴스를 초기화하고 대기 핸들이 처음에 종료 상태인지 여부를 지정합니다. 자동 또는 수동으로 재설정합니다. 재설정. 대부분의 경우 첫 번째 매개변수에 false를 사용하여 새 인스턴스가 기본적으로 "종료되지 않은" 상태가 되도록 합니다. 두 번째 매개변수 EventResetMode는 총 두 개의 값을 갖는 열거형입니다:

    1. EventResetMode.AutoReset: Set()이 호출되면 현재 EventWaitHandle은 다음과 같습니다. 종료된 상태에서 현재 EventWaitHandle에 차단된 스레드가 있으면 EventWaitHandle은 스레드를 해제한 후 자동으로 재설정(Reset()을 자동으로 호출하는 것과 동일)하고 종료되지 않은 상태로 전환됩니다. 그러면 나머지 차단된 스레드(있는 경우)는 계속 차단됩니다. Set()을 호출한 후 차단된 스레드가 없으면 스레드가 이벤트를 기다리려고 할 때까지 EventWaitHandle은 "종료됨" 상태로 유지됩니다. 그 후에는 EventWaitHandle이 자동으로 재설정되고 차단됩니다. 그 이후의 모든 스레드.

    2. EventResetMode.ManualReset: 종료되면 EventWaitHandle은 수동 재설정 전에 모든 대기 스레드를 해제합니다. 즉 Reset() 까지 종료된 상태로 유지됩니다. 라고 불리는.

    이제 Set()이 Monitor.Pulse()/PulseAll()과 각각 유사한 경우를 명확하게 알 수 있습니다.

    • EventWaitHandle이 AutoReset 모드에서 작동할 때 Set()은 깨우기 기능 측면에서 Monitor.Pulse()와 유사합니다. 현재 Set()은 차단된 많은 스레드(여러 개가 있는 경우) 중 하나만 깨울 수 있습니다. 그러나 둘 사이에는 여전히 몇 가지 차이점이 있습니다.

    1. Set()의 기능은 단순히 "깨우기"가 아니라 "해제"하여 스레드를 계속할 수 있도록 하는 것입니다. 반대로, Pulse()에 의해 깨어난 스레드는 다시 Running 상태에 들어가고 개체 잠금을 위한 경쟁에 참여합니다.

    2. Pulse() 호출 상태는 유지되지 않습니다. 따라서 대기 중인 스레드가 없을 때 Pulse()가 호출되면 Monitor.Wait()를 호출하는 다음 스레드는 마치 Pulse()가 호출된 적이 없는 것처럼 계속 차단됩니다. 즉, Monitor.Pulse()는 다음 WaitXXX()로 계속되는 Set()과 달리 호출될 때만 적용됩니다.

  • ManualReset 모드에서 작동하는 EventWaitHandle의 Set() 메서드가 호출되면 해당 깨우기 기능은 Monitor.PulseAll()과 유사합니다. 신호를 받고 깨어납니다. 둘의 차이점은 위와 똑같습니다.

  • EventWaitHandle의 다른 생성자를 살펴보겠습니다.

    • EventWaitHandle(BooleaninitialState, EventResetMode mode, String name): 처음 두 매개변수는 이미 살펴봤고, 세 번째 매개변수 이름은 시스템 전체의 동기화 이벤트를 지정하는 데 사용됩니다. 이름. 예, Mutex 기사에서 언급했듯이 부모 클래스 WaitHandle에는 Mutex와 같은 프로세스 도메인을 교차할 수 있는 기능이 있으므로 전역 EventWaitHandle을 생성하고 나중에 프로세스 간 알림에 사용할 수 있습니다. 이름은 여전히 ​​대소문자를 구분하며 이름 지정 접두사 문제가 여전히 있습니다. 여기를 참조하세요. 이는 이름이 null이거나 비어 있는 string인 경우 이름이 지정되지 않은 로컬 EventWaitHandle을 생성하는 것과 같습니다. 여전히 동일하지만 시스템에 동일한 이름의 EventWaitHandle이 이미 있으므로 동일한 이름의 EventWaitHandle을 나타내기 위해 하나의 인스턴스만 반환될 수 있습니다. 따라서 결국 여전히 동일합니다. 이 EventWaitHandle이 사용자에 의해 먼저 생성되었는지 알아야 하는 경우 다음 두 생성자 중 하나를 사용해야 합니다.

    • EventWaitHandle(BooleaninitialState, EventResetMode mode, String name, out BooleancreatedNew): CreateNew는 EventWaitHandle이 성공적으로 생성되었는지 여부를 나타내는 데 사용되며 true는 성공을 나타냅니다. , false 동일한 이름의 이벤트가 이미 존재함을 나타냅니다.

    • EventWaitHandle(BooleaninitialState, EventResetMode mode, String name, out Boolean CreateNew, EventWaitHandleSecurity): 보안 문제에 대해서는 이 생성자의 예제를 직접 확인하세요. 전역 MutexEventWaitHandle의 보안 문제는 Mutex의 보안 문제보다 더 주의를 기울여야 합니다. 왜냐하면 해커가 동일한 이벤트 이름을 사용하여 신호를 보내거나 스레드를 구성하여 비즈니스 논리에 심각한 해를 끼칠 수 있기 때문입니다.

    MSDN 데모


    rreee


    위 내용은 .NET 동기화 및 비동기 EventWaitHandle의 상세 내용입니다. 자세한 내용은 PHP 중국어 웹사이트의 기타 관련 기사를 참조하세요!

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