我正在担任支持工程师,在失败的流程转储中,我看到有一些锁。
使用Windbg(Visual Studio无法正确处理调用堆栈),我发现一个函数(void _getDataFromSomeScreen(context) {
Navigator.push(
context, MaterialPageRoute(builder: (context) => SomeScreen()))
.then((data) => _bloc.streamController.sink.add(data));
}
)又回来了。简而言之,该函数使用一个关键部分并调用一个子函数(ClassName::F()
),该子函数正在调用同一关键部分:
ClassName::f_sub()
每次都使用相同的关键部分int ClassName::f_sub(){
EnterCriticalSection(&m_cs);
...
LeaveCriticalSection(&m_cs);
return ...;
}
int ClassName::F() {
EnterCriticalSection(&m_cs);
...
int temp = f_sub();
...
LeaveCriticalSection(&m_cs);
return ...;
}
(属性m_cs
)。
我认为,这使得以下顺序成为可能:
ClassName
我的分析是否正确,这是否意味着建议对主要功能和子功能使用不同的关键部分?
答案 0 :(得分:1)
我的分析是否正确,这是否意味着建议对主要功能和子功能使用不同的关键部分?
来自Microsoft Docs(重点是我):
在线程拥有关键部分的所有权之后,它可以使 对EnterCriticalSection或TryEnterCriticalSection的其他调用 而不阻止其执行。这样可以防止线程 在等待关键部分的过程中陷入僵局 已经拥有。线程每次进入关键部分 EnterCriticalSection和TryEnterCriticalSection成功。 线程 每次进入LeaveCriticalSection都必须调用一次 关键部分。
因此,您描述的内容不会发生。多次进入关键部分非常好,并且需要完全保留多次。