dll如何处理来自多个进程的并发性
How do DLLs handle concurrency from multiple processes?
我从Eric Lippert的回答中理解到"两个进程可以共享非私有内存页"。如果20个进程都加载相同的DLL,那么这些进程都共享该代码的内存页。它们不共享虚拟内存地址空间,而是共享内存。"
现在,如果硬盘上相同的DLL文件,在加载到应用程序后,将共享相同的物理内存(RAM或页文件),但映射到不同的虚拟内存地址空间,这不会使并发处理变得相当困难吗?
据我所知,c++中的并发概念更多的是关于处理线程——一个进程可以启动多个线程,每个线程可以在一个单独的核心上运行,所以当不同的线程同时调用DLL时,可能会有数据竞争,我们需要互斥,锁,信号,条件变量等。
但是DLL如何处理多进程呢?同样的数据竞赛概念也会发生,不是吗?有什么工具可以处理这个问题?还是相同的工具集吗?
现在,如果硬盘上相同的DLL文件,加载到应用程序后,将共享相同的物理内存(无论是RAM或页文件),但映射到不同的虚拟内存地址空间,这不会使并发处理相当困难吗?
正如其他答案所指出的,如果共享内存在初始化后从不写入,那么并发性问题就无关紧要了,这通常是dll的情况。如果您试图通过写入内存来改变DLL中的代码或资源,那么很有可能您在某个地方有一个坏指针,最好的办法是由于访问冲突而崩溃。
然而,我也想简单地跟进你的关注:
在实践中,我们非常努力地避免这种情况发生,因为当它发生时,在第一次加载代码页时可能会出现严重的用户明显的性能问题。(当然,工作集可能会大量增加,这会导致其他性能问题。)…映射到不同的虚拟内存地址空间…
DLL中的代码通常包含硬编码的虚拟内存地址,假设代码将加载到编译时已知的虚拟内存"基"地址中。如果在运行时违反了这个假设(例如,因为已经存在另一个DLL),那么所有这些硬编码地址都需要在运行时打补丁,这是非常昂贵的。
如果您想了解历史细节,请参阅Raymond关于该主题的文章:https://blogs.msdn.microsoft.com/oldnewthing/20041217-00/?p=36953/
DLL包含多个"段",每个段都有一个描述符告诉Windows它的Characteristics
。这是一个32位DWORD。代码段显然设置了代码位,通常也设置了可共享位。只读数据也可以是可共享的,而可写数据通常没有可共享标志。
现在,可以在额外的段上设置不同寻常的特征组合:可写和可共享。这不是默认值,而且确实可能导致竞争条件。所以你的问题的最终答案是:这个问题主要是通过段的默认特征来避免的,其次,任何具有非标准特征的段的DLL都必须处理自己造成的问题。
- boost::进程间消息队列引发错误
- 在进程中对同一管道进行读取和写入时C++管道出现问题
- 是否可以通过C++扩展强制多个python进程共享同一内存
- IPC使用多个管道和分支进程来运行Python程序
- 控制允许动态运行c++的并发操作数
- 异常属于C++中的线程还是进程
- WMI检测进程创建事件-c++
- 节俭并发:未解决的外部问题
- c++多进程编写一个唯一的文件
- 如何在C++中将函数发送到另一个进程
- 在Qt Creator中,如何在连接到正在运行的进程后查看控制台输出
- 终止 QProcess 不会终止子进程
- 两个并发的 Python 进程可以在 Boost Python 中运行吗?
- 使用来自多个进程的 pantheios 并发写入日志文件
- 进程之间的并发文件写入
- MFC:当进程在win32文本区域(MFC应用程序)中执行时,异步(并发)显示进程的输出
- 对Linux和Windows的多个进程的并发状态文件操作超出了我们的控制
- 从多个进程并发访问共享内存DLL
- 是否可以使用boost构建并发进程间消息队列
- dll如何处理来自多个进程的并发性