c# - 我可以在此 ManualResetEvent 中使用锁来确保线程安全吗?
问题描述
假设我有两个操作计数的函数和一个定期触发的 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 吗?如果在持有锁的同时等待重置事件,我是否会面临死锁的风险?
解决方案
如果我理解您,那么是的,如果您选择适当锁定的内容,它将起作用。可能有一种更精细的方法可以做到这一点,但到目前为止我认为这没有任何问题
void IncrementCount()
{
mre.Wait();
// lets not cause a race, lock until OverwriteCount is finished
lock (_sync)
{
_myCount++;
}
}
void OverwriteCount(int newValue)
{
// lock this so we can assure the count is updated
lock (_sync)
{
mre.Reset(); // unsignal the event, blocking threads
_myCount = newValue;
}
}
void OnTimer()
{
Console.WriteLine(_myCount);
mre.Set(); // signal the event
}
推荐阅读
- amazon-web-services - DynamoDB PutItem 不断覆盖以前的条目
- java - 如何实现在“z”字母后考虑“-”符号的字符串比较器
- c# - Quickfixn-FIXT1.1 和 FIX5.0 版本 MarketDataSnapshotFullRefresh 360T “标签出现不止一次”
- c# - 运行时编译不适用于 .net 核心
- c# - 使用 Graph API 将 Web 应用程序网站的访问权限仅限于特定用户
- javascript - 等待页面在硒中完全加载节点js
- unity3d - 惯性模块 LSM9DS1 Arduino 的方向问题
- python - 没有索引在列中 - 不能做单线箱线图
- android - Kotlin LiveData 协程
- python - 我从 alphavantage API 得到了这个 JSON(这是一个小片段),我只需要提取关闭的数据,但不知道如何