17(39)---windows internal 第6版 mark david alex

线程位于进程内,是windows调度执行的基本单位。没有线程,进程将不能运行。线程由以下内容组成:
一组cpu寄存器,代表当前的CPU状态
两个栈。当线程运行于内核态时,使用内核栈;运行在用户态时,使用内核栈。
私有存储区域,成为线程局部存储(thread-local storage TLS)。供子系统,运行时库和dll使用。
线程id,用于唯一标识线程。线程id是内部结构client ID的一部分。进程id和线程id从同样的名字空间生成,他们不会重复。
安全上下文(可选),常用于多线程服务器中,扮演客户端的安全上下文。
寄存器,栈和私有存储区域合起来被称为线程的上下文,具体内容依机器架构而有所不同。GetThreadContext可以得到对应的数据。
注意:64位系统上的32位程序包含32位和64位两个上下文。wow64用来切换32位和64位状态。这些线程拥有两个栈和两个上下文,GetThreadContext返回的是64位上下文。Wow64GetThreadContext返回32位的上下文。第三章有wow64的详细介绍。
纤程和用户态调度线程
由于牵涉到内核调度器,调度线程是一个昂贵的操作,特别是两个线程之间经常互相切换的话。Windows提供两个机制来减少这种开销:纤程和用户态调度线程(user-mode scheduling UMS)。
纤程允许程序调度自己的“线程”,而不是依赖于windows的内建调度算法。纤程经常被称为轻量级线程,kernel32.dll的用户态代码实现了调度过程,所以调度对内核是不可见的。使用纤程很方便,首先需要调用ConvertThreadToFiber,把正在运行的线程转化为纤程。然后,此纤程可以调用CreateFiber创建其他纤程,每个纤程可以有一组纤程。和线程不同的是,纤程不会自动执行,只有在SwitchToFiber被调用后才能执行。然后,纤程会一直运行,直到退出或者SwitchToFiber被调用。更详细的信息,请参考SDK。
UMS 线程,只有在64位的windows下才能使用。它不仅拥有纤程的优点,同时也弥补了纤程的缺点。UMS线程有内核线程状态,因此可以发起系统调用,共享/争夺资源,并且拥有线程状态。如果多个UMS线程只在用户态工作,它们可以定期的交换上下文,在用户态完成上下文切换,从而避免内核调度器的介入。在内核来看,同样的线程一直在运行,没有任何变化。当UMS线程执行一个操作(比如说系统调用),需要进入内核时,它切换到内核模式线程,这一过程称为直接线程切换。第五章有进一步介绍。
每个线程有独立的上下文环境,进程中的所有线程共享进程的虚拟地址空间以及其他资源,这意味着所有线程对进程的虚拟地址空间都有读写权限。默认情况下,线程不能访问其他进程的虚拟地址空间。其他进程可以通过共享内存区(内存映射文件)共享或者通过ReadProcessMemory和WriteProcessMemory等API来读写(需要有权限打开别的进程).
除了线程和私有的地址空间之外,进程还包括安全上下文以及打开的内核对象(文件,共享内存、同步对象等)句柄列表。
访问令牌(access token)保存了进程的安全上下文信息。它包括进程的安全标示和凭证信息。线程一般没有访问令牌,但是可以获取一个,这样能够扮演其他进程的安全上下文(包括远程系统的),而不影响进程内的其他线程(第6章有进一步描述)
内存管理器用虚拟地址描述符(virtual address descriptors (VADs))来管理虚拟地址的使用情况。第2部分第10章有详细描述。
作业(job)是windows为进程模型提供了一个扩展。它能够管理一组进程。为作业中的进程提供限制和属性控制,还能记录基本审计信息(包括当前进程和已经结束的进程)。作业弥补了windows没有结构化进程树的缺点,并且在很多情况下比unix的进程树更强大。
工作,进程,线程的详细信息,请看第五章。
虚拟内存
windows实现了一个基于线性地址空间的虚拟内存系统。每个进程都会认为自己有足够大的私有地址空间。虚拟内存提供的内存逻辑视图和内存物理布局可能并不对应。通过硬件的帮助,内存管理器在运行期把虚拟内存映射为为物理内存(数据真正存贮的位置)。通过控制保护和映射机制,操作系统可以保证进程之间不会互相影响。表1-3显示了这种情况。3个连续的虚拟内存,在物理内存上其实是不连续的。
由于大部分系统的物理内存,比所有进程用到的虚拟内存总量要少得多,内存管理器会把一部分内存换页到硬盘上。这样可以释放一部分物理内存以便其他进程或者操作系统本身使用。如果随后需要访问这部分内存,内存管理器从硬盘重新读入。应用程序不要做任何改动,就能享受换页的好处,因为有硬件的支持,不需要进程或者线程参与。
虚拟地址空间的大小根据硬件平台不同而变化。在32位x86系统上,最大值是4GB。默认情况下,windows将0x00000000--0x7FFFFFFF分给进程使用,0x80000000到0xFFFFFFFF给操作系统本身使用。windows提供了一个启动选项(启动配置数据库中的increaseuserva,第13章第二部分有介绍),可以使带有特殊标志的进程有3GB的地址空间。该选项允许数据库服务器之类的程序把更多的内容映射到进程的地址空间中,从而减少对映射数据库子集视图的需求。图1-4显示了32位系统上常见的虚拟内存地址布局(increaseuserva允许应用程序使用2-3GB之间的任意数量内存)
3GB虽然比2GB大了点,对于超大型数据库来说,仍然是不够的。在32位系统上,windows通过地址窗口扩展(Address Windowing Extension(AWE))来解决这个问题。AWE允许分配高达64GB的内存,然后映射内存视图或者窗口到2GB的地址空间中。虽然AWE把映射内存的负担交给了开发者,但是的确解决了32位系统上内存空间不足的问题。
64位windows提供了更大的地址空间:7152GB在IA64系统上,8192BG在X64系统上。表1-5显示了简化的64位系统地址空间布局(第二部分第10章有详细描述)。注意,这些值并非平台的架构限制。64位地址空间大小可以超过170亿GB,但是目前的64位硬件将地址空间限制为较小的值,64位windows将这个值进一步限制在8192GB。
内存管理器的实现细节,包括地址翻译如何工作、windows如何管理物理内存等,在第10章第二部分有详细描述。
内核模式和用户模式
为了防止用户用用程序访问和修改操作系统数据,windows启用两个处理器模式(在支持多个模式的cpu上也是如此),分别是内核模式和用户模式。应用程序运行在用户模式下,而操作系统代码(如系统服务和驱动程序)运行在内核模式下。内核模式可以访问所有的内存和cpu指令。通过给操作系统提供更高的系统特权,处理器为操作系统设计者提供了必要的基础,来保证一个错误的应用程序不会破坏系统的整体稳定性。
x86和x64的处理器定义了4个特权等级(也称为环),来保护系统代码和数据不会被低级别的代码修改。windows使用了特权等级0作为内核模式 , 特权等级3作为用户模式。之所以只使用两个模式,是由于windows曾经支持的某些硬件平台(Compaq Alpha 和 Silicon Graphics MIPS)只有两个特权层次。
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值