【发布时间】:2017-11-27 09:45:30
【问题描述】:
从albahari atricle学习多线程。
我需要在下面的示例中使用锁 _locker 吗?我想不会,因为_message 受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);
}
}
}
}
【问题讨论】:
-
我看不出删除
lock可以改变这个例子中的执行顺序。 -
不需要锁,两个 AutoResetEvents 之间的乒乓球提供了同步,确保线程不能同时访问变量。 WaitOne() 调用提供了一个内存屏障,确保变量更新对另一个线程可见。这些偶然的障碍不是很漂亮,但并不少见。您强烈支持使用 Barrier 类,它的 SignalAndWait() 方法使此代码更易于理解。而且效率更高。看得懂的代码避免了线程错误,高效的代码让每个人都开心。
标签: c# multithreading thread-synchronization