我正在查看遗留代码。我看到有两个 DLL 共享通用代码库,因此 Dll 共享一些通用方法和同步对象名称。这意味着它们都创建和使用同名的关键部分同步对象。我知道即使在 Windows 上的进程中,两个模块之间也不会共享全局/静态变量。理论上,我们正在创建两个独立的同步对象,它们在各自的 DLL 中独立运行,所以这应该不是问题。
现在考虑这种情况 - 有一个进程 Proc.exe 加载两个 DLL A.dll 和 B.dll 如上所述。这两个 DLL 将有一个共同的临界区对象名称 g_cs 和一些共同的方法名称,现在考虑一个常见的方法名称 foo() 是线程安全的,如下所示:
foo()
{
....
EnterCriticalSection(g_cs)
....
....
LeaveCriticalSection(g_cs)
....
....
}
假设两个线程 T1 和 T2 在 Proc.exe 中运行并且当前在 foo() 方法中。有时我观察到一个僵局。从日志中,我看到 t1 和 t2 一个接一个地同时获取critical_section g_cs,之后再也没有解锁'g_cs'。我的理解是,只有在 A.dll 和 B.dll 的上下文中运行时,T1 和 T2 才能同时获取“g_cs”。是这样的话,那么这个执行应该是安全的吗?
我的理解是临界区对象属于进程,所以问题可能是因为两个 dll 中同步对象的通用名称“g_cs”。但理论上这不应该发生。