1

我正在查看遗留代码。我看到有两个 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”。但理论上这不应该发生。

4

1 回答 1

0

如前所述,提供相同的变量名称不是问题。即使关键部分以某种方式被合并,也不会导致死锁。

您应该在死锁时附加调试器。可能线程堆栈已经指向问题所在。如果确实是死锁,请将关键部分添加到调试器的监视中。将有一个显示所有者线程 ID 的字段。转到那个线程(从“线程”窗口中选择它)并检查它的堆栈。

于 2013-08-22T14:27:48.623 回答