我正在查看遗留代码。我看到有两个 DLL 共享公共(public)代码库,因此 Dll 共享一些公共(public)方法和同步对象名称。这意味着它们都创建并使用同名的临界区同步对象。我知道global/Static variables are not shared between two modules即使在 Windows 上的进程中。理论上,我们正在创建两个独立的同步对象,它们在各自的 DLL 中独立运行,因此这应该不是问题。
现在考虑这种情况 - 有一个进程 Proc.exe 加载了上面提到的两个 DLL A.dll 和 B.dll。这两个 DLL 将有一个公共(public)的临界区对象名称 g_cs 和一些公共(public)方法名称,现在考虑一个公共(public)方法名称 foo( ) 是线程安全的,如下所示:
foo()
{
....
EnterCriticalSection(g_cs)
....
....
LeaveCriticalSection(g_cs)
....
....
}
假设两个线程 T1 和 T2 在 Proc.exe 中运行并且当前在 foo() 方法中。 有时我观察到一个僵局。从日志中我看到 t1 和 t2 同时一个接一个地获取了 critical_section g_cs,之后再也没有解锁 'g_cs'。我的理解是,T1 和 T2 只有分别在 A.dll 和 B.dll 的上下文中运行时,才能同时获取 'g_cs'。是这样的话,那么这次执行应该是安全的吗?
我的理解是关键部分对象属于进程,所以问题可能是因为两个 dll 中同步对象的通用名称“g_cs”。但理论上这不应该发生。
最佳答案
如前所述,赋予相同的变量名不是问题。即使临界区以某种方式被合并,也不会导致死锁。
您应该在死锁时刻附加调试器。线程堆栈可能已经指出了问题所在。如果确实是死锁,请将关键部分添加到调试器的监视中。将有一个字段显示所有者线程 ID。转到那个线程(从“线程”窗口中选择它)并检查它的堆栈。
关于c++ - 在同一进程中使用的两个模块中使用同步对象的通用名称是否安全?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/18372474/