【发布时间】:2019-06-13 01:28:22
【问题描述】:
假设我有两个操作计数的函数和一个定期触发的 OnTimer 函数。
void IncrementCount()
{
_myCount++;
}
void OverwriteCount(int newValue)
{
_myCount = newValue;
}
void OnTimer()
{
Console.WriteLine(_myCount);
}
我的愿望是,如果/当 OverwriteCount 被调用时,IncrementCount 在计时器函数执行之前无法执行。
我最初的想法是使用 ManualResetEvent 来帮助同步行为:
private static ManualResetEventSlim mre = new ManualResetEventSlim(initialState: true);
void IncrementCount()
{
mre.Wait(-1); // can't increment until the event is signaled
_myCount++;
}
void OverwriteCount(int newValue)
{
mre.Reset(); // unsignal the event, blocking threads
_myCount = newValue;
}
void OnTimer()
{
Console.WriteLine(_myCount);
mre.Set(); // signal the event
}
我担心的是一个退化的多线程场景,其中线程 A 在 IncrementCount() 中通过了 mre.Wait() 但实际上还没有增加 _myCount。线程 B 然后调用 mre.Reset() 并覆盖 _myCount。然后线程 A 转一圈并增加 _myCount。
我是否可以通过在 IncrementCount() 和 OverwriteCount() 中添加一个锁来解决这个问题,以确保一次只有一个线程可以修改 _myCount?如果在持有锁的同时等待重置事件,我是否会面临死锁的风险?
【问题讨论】:
标签: c# .net concurrency