发信人: skyice()
整理人: skyice(2000-06-22 00:30:41), 站内信件
|
共享内存
在本章其余部分,我们将重点关注用来分配共享内存(即两个或多个进
程之间的可共享内存)的那部分 Win32 API。从本章开始到现在,我们的讨
论焦点一直是私有内存分配。因为大多数进程数据是私有数据,所以私有数
据无疑更重要。可能由于这个原因,Win32 提供的私有数据例程比共享数据
例程多。私有进程内存的重要好处是它提高了系统的稳定性。因为它减少了
一个应用程序重写另一个应用程序的内存区的危险,所以它成为为进程分配
的默认内存类型。要共享内存,应用程序必须显式地取代这种默认类型。
对应用程序开发人员来说,私有内存和共享内存之间的区别或许看起来
很随意。不管怎么说,在这一会是私有的数据,下一次也许就能共享。然而,
对操作系统来说,私有内存和共享内存的区别是基本而且重要的。在本章前
面曾说过,Win32 API 为揭示这个区别,提供了两个例程来创建地址空间:
VirtualAlloc() 用来创建私有地址空间,MapViewOfFile() 创建共享地
址空间。在进程分配页之前(无论在 Windows 98 还是在 Windows NT上)
都必须决定是否允许共享。下面让我们看一看每个操作系统处理共享内存和
私有内存之间区别的巧妙方法。
Windows 98 把私有内存页放在一块地址空间中,而把共享内存页放在
另一块中。私有页驻留在 4MB 到 2GB 之间。本章前面说过,当发生从一个
Win32 进程向另一个 Win32 进程的上下文切换时,一组页被映射到这个地
址范围,而另一组页被映射出去,这个动作通过更新 CPU 的页表完成。另
一方面,共享页则驻留在 2GB到3GB 之间。在上下文切换时,Windows 98
内存管理器并不接触映射到这个区域的页的页表。通过把共享页单独留出来,
Windows 98 内存管理器使进程间共享内存非常快捷而迅速。
Windows 98 把可执行文件映象放到进程地址空间的方式引出了一个明
显的矛盾。因为可执行文件是可共享的实体,你也许认为 Windows 98将把
它们放到共享地址范围。尽管有一种类型的 DLL(系统 DLL)被载人到共享
地址范围,但私有可执行文件并不驻留在那里。Windows 98 把私有可执行
文件(.EXE)和私有动态链接库(.DLL)映射到私有地址空间。通过把它们
放在私有范围内,Windows 98 可以精心选择如何处理私有可执行文件。例
如,为有效使用私有四人和私有 EXE 文件,Windows 98 把单独一组物理
页映射到一些进程的地址空间。
Windows NT 也区分共享页和私有页,其方式比 Windows 98 使用的区
分不同地址范围的方式更敏感。其区别与 Windows NT 如何设置处理器页表
有关。在 Windows NT 上,私有页简单地使用了在本章开头讲过的 Intel-
86 分页内存寻址方案。所有的进程都有自己的页目录和页表,在上下文切换
时,CPU 的 CR3 寄存器被更新,以映射新的地址空间。
Windows NT 用比 Windows 98 更敏感的方式把共享页和私有页区分开
来。对共享页中的内存位置的访问将引起一个页故障。在许多操作系统中,
页故障表示发生了驻留在页文件中的页或内存地址错,诸如引用了一个NULL
指针。Windows NT 能识别这两种传统页使用故障,但添加了一些其他的内
容使共享内存对进程可见。当故障发生在共享页范围内时,Windows NT 响
应该页故障,把共享页神奇地显现给进程。这样的访问错页在页表中以原型
页表项(prototype page table entry)的格式作了特殊编码。原型页表
项包含了对一组指明共享页位置的系统页表(私有页不需要的另一层次的页
表)的引用。就象在 Windows 98 上一样,把页作为共享还是私有的决定对
Windows NT 如何把页塞进进程的地址空间有深刻的影响。
我们随便地介绍了 Windows 98 和 Windows NT 之间的区别,以促进
更好地了解它们怎样操作。现在我们还没有办法编写一些代码,通过在 Wi-
ndows 98 上查找 2GB 和 3GB 之间的指针值以测试共享内存。(这个特定
于实现的特征也许在未来的版本中会有所改变。要检查共享页,可调用 Vi-
rtualQuery()。)但也不必担心 Windwos NT 会由于处理共享内存访问错
误所需附加开销而运行缓慢;用于处理这些页故障所需的处理器时间比绘制
一条窗口边框线所需时间还要少得多。
有一个通用元素把所有的共享页统一起来。无论使用哪种格式,在 Wi-
n32 中的所有内存共享都依赖于Win32 的内存映射文件 I/O 支持。内存映
射文件使用共享内存把通用的基于文件的数据映象提供给两个或更多进程。
关于内存映射文件 I/O,不太明显的东西是它提供了内存共享。Win32
进程中的共享内存把一部分操作系统的虚拟内存页文件象内存映射文件一样
使用。尽管强调的是共享内存,但内存页中的数据迟早要放到磁盘上。但是
共享页不是在一个永久的命名文件中,而是驻留在系统页文件中。
在下一节,我们探索进程间共享内存的四种方式。从内存映射文件开始,
因为它们是其他共享类型的主干。然后看一看未在特别命名的内存映射文件
中的内存页的共享。我们将看到两种共享页类型:动态分配的和静态分配的。
-- 我想我是海,宁静的深海
不是谁都明白 ...
※ 来源:.月光软件站 http://www.moon-soft.com.[FROM: 202.99.93.131]
|
|