DLL如何处理来自多个进程的并发?

ath*_*hos 0 c++ dll concurrency

我从Eric Lippert的回答中了解到"两个进程可以共享非私有内存页面.如果二十个进程都加载了相同的DLL,那么进程都共享该代码的内存页面.它们不共享虚拟内存地址空间,它们共享记忆."

现在,如果硬盘上的相同DLL文件在加载到appliations之后会共享相同的物理内存(无论是RAM还是页面文件),但是映射到不同的虚拟内存地址空间,这样就不会让它很难处理并发?

据我所知,C++中的并发概念更多的是关于处理线程 - 一个进程可以启动多个线程,每个线程都可以在一个单独的核心上运行,所以当不同的线程同时调用DLL时,可能会有数据竞争,我们需要互斥锁,锁,信号,条件变量等.

但是DLL如何处理多进程?数据竞赛的概念会发生,不是吗?有哪些工具可以解决这个问题?还是一样的工具集?

Eri*_*ert 5

现在,如果硬盘上的相同DLL文件在加载到应用程序后,将共享相同的物理内存(无论是RAM还是页面文件),但映射到不同的虚拟内存地址空间,这不会让它变得非常困难处理并发?

正如其他答案所指出的那样,如果共享内存在初始化之后永远不会被写入,则并发问题无关紧要,这通常是DLL的情况.如果你试图通过写入内存来改变DLL中的代码或资源,那么你可能在某个地方有一个糟糕的指针,最好的办法就是在访问冲突时崩溃.

不过,我还想简要介绍一下你的担忧:

...映射到不同的虚拟内存地址空间...

在实践中,我们非常努力地避免这种情况发生,因为当它发生时,在第一次加载代码页时可能会出现严重的用户注意到的性能问题.(当然,工作集可能会大幅增加,这会导致其他性能问题.)

DLL中的代码通常包含硬编码的虚拟内存地址,假设代码将被加载到编译时已知的虚拟内存"基本"地址.如果在运行时违反了这个假设 - 例如,那里已经存在另一个DLL - 那么所有那些硬编码的地址都需要在运行时进行修补,这是很昂贵的.

如果您需要一些历史细节,请参阅Raymond关于该主题的文章:https://blogs.msdn.microsoft.com/oldnewthing/20041217-00/?p = 36953 /