albahari atricle에서 멀티 스레딩 학습 중입니다. 아래 표본에 _locker
자물쇠가 필요합니까? 이 (가) EventWaitHandle
에 의해 보호되어 있기 때문에 나는 그렇지 않다고 생각합니다. 내가 맞습니까?EventWaitHandle을 가지고 있다면 잠금 장치가 필요합니까
class TwoWaySignaling
{
static EventWaitHandle _ready = new AutoResetEvent (false);
static EventWaitHandle _go = new AutoResetEvent (false);
static readonly object _locker = new object();
static string _message;
static void Main()
{
new Thread (Work).Start();
_ready.WaitOne(); // First wait until worker is ready
lock (_locker) _message = "ooo";
_go.Set(); // Tell worker to go
_ready.WaitOne();
lock (_locker) _message = "ahhh"; // Give the worker another message
_go.Set();
_ready.WaitOne();
lock (_locker) _message = null; // Signal the worker to exit
_go.Set();
}
static void Work()
{
while (true)
{
_ready.Set(); // Indicate that we're ready
_go.WaitOne(); // Wait to be kicked off...
lock (_locker)
{
if (_message == null) return; // Gracefully exit
Console.WriteLine (_message);
}
}
}
}
이 예제에서 '잠금'을 제거하면 실행 순서가 변경 될 수 있습니다. – Rotem
잠금이 필요하지 않으므로 두 AutoResetEvent 간의 ping-ponging이 동기화를 제공하여 스레드가 변수에 동시에 액세스 할 수 없도록합니다. WaitOne() 호출은 다른 스레드에서 변수 업데이트를 볼 수 있도록 메모리 장벽을 제공합니다. 우발적 인 장벽의 이러한 종류의 아주 예쁜 아니지만 드물지 않습니다. Barrier 클래스를 사용하는 것이 좋습니다. SignalAndWait() 메서드를 사용하면이 코드를 훨씬 쉽게 이해할 수 있습니다. 그리고 훨씬 더 효율적입니다. 이해할 수있는 코드는 스레딩 버그를 피하고, 효율적인 코드는 모두를 행복하게 만듭니다. –