线程(进程)上下文

转自:http://blog.youkuaiyun.com/hgy413/article/details/7562389(要是有图片等显示不出来查看此链接)

让我们来看看CreateThread都干了些什么。

线程创建和初始化示意图
        上图显示了系统在创建线程和对线程进行初始化时必须做些什么工作。调用CreateThread可使系统创建一个线程内核对象。该对象的初始使用计数是2(在线程停止运行和从CreateThread返回的句柄关闭之前,线程内核对象不会被撤消)。线程的内核对象的其他属性也被初始化,暂停计数被设置为1,退出代码始终为STILL_ACTIVE(0 x 1 0 3),该对象设置为未通知状态。
        一旦内核对象创建完成,系统就分配用于线程的堆栈的内存。该内存是从进程的地址空间分配而来的,因为线程并不拥有它自己的地址空间。然后系统将两个值写入新线程的堆栈的上端(线程堆栈总是从内存的高地址向低地址建立)。写入堆栈的第一个值是传递给CreateThread的pvParam参数的值。紧靠它的下面是传递给CreateThread的pfnStartAddr参数的值。每个线程都有它自己的一组C P U寄存器,称为线程的上下文。该上下文反映了线程上次运行时该线程的CPU寄存器的状态。线程的这组C P U寄存器保存在一个CONTEXT结构。CONTEXT结构本身则包含在线程的内核对象中。
    指令指针和堆栈指针寄存器是线程上下文中两个最重要的寄存器。线程总是在进程的上下文中运行的。因此,这些地址都用于标识拥有线程的进程地址空间中的内存。当线程的内核对象被初始化时,CONTEXT结构的堆栈指针寄存器被设置为线程堆栈上用来放置pfnStartAddr的地址。当线程完全初始化后,系统就要查看CREATE_SUSPENDED标志是否已经传递给CreateThread。如果该标志没有传递,系统便将线程的暂停计数递减为0,该线程可以调度到一个进程中。然后系统用上次保存在线程上下文中的值加载到实际的C P U寄存器中。这时线程就可以执行代码,并对它的进程的地址空间中的数据进行操作。
    在这里,我还要简单的描述一下CONTEXT结构,因为WIN32是抢占式操作系统,一个线程几乎不可能永远的占据CPU,也就是说,它会在一定时间后(在WINDOWS中,大概式20ms的时间),被CPU放在一边,一段时间之后,才可以重新获得CPU时间片,此时就有一个问题,线程现在执行到了那里,CPU在再次分配给它时间片执行的时候,必须知道这些信息,难道要从0开始吗?CONTEXT结构的作用就是用来解决这个问题。
    在Platform SDK中,你可以看到下面的信息:
    “CONTEXT结构包含了特定处理器的寄存器数据。系统使用CONTEXT结构执行各种内部操作。目前,已经存在为Intel、MIPS、Alpha和PowerPC处理器定义的CONTEXT结构。若要了解这些结构的定义,参见头文件WinNT.h”。
       该文档并没有说明该结构的成员,也没有描述这些成员是谁,因为这些成员要取决于Windows在哪个CPU上运行。实际上,在Windows定义的所有数据结构中,CONTEXT结构是特定于CPU的唯一数据结构。那么CONTEXT结构中究竟存在哪些东西呢?它包含了主机C P U上的每个寄存器的数据结构。在x86计算机上,数据成员是Eax、Ebx、Ecx、Edx等等。如果是Alpha处理器,那么数据成员包括IntV0、IntT0、IntT1、IntS0、In tRa和IntZero等等。
        Windows实际上允许查看线程内核对象的内部情况,以便抓取它当前的一组CPU寄存器。若要进行这项操作,只需要调用GetThreadContext函数。关于此函数的使用,我们下次再说。



<think>好的,我需要回答用户关于进程线程上下文切换的区别及性能影响的问题。首先,我应该回顾一下用户提供的引用内容,确保正确引用信息。用户给出的四个引用主要讨论了线程进程上下文切换的不同之处,包括虚拟内存空间、资源切换、性能损耗如寄存器切换、缓存失效和TLB刷新等。 首先,我需要明确进程线程的基本概念。进程是资源分配的基本单位,拥有独立的虚拟内存空间、文件描述符等资源,而线程是调度的基本单位,属于同一进程线程共享这些资源。根据引用[1],线程切换时虚拟内存空间不变,而进程切换时虚拟内存空间改变。这是关键区别之一。 接下来,上下文切换的具体内容。进程切换涉及更多资源的保存和恢复,比如页表、文件描述符等,而线程切换只需处理私有数据如寄存器和栈。引用[3]提到线程切换时共享资源不需要修改,只需要保存私有数据,而进程切换需要切换全部资源。 然后考虑性能影响。引用[1]和[4]指出,进程切换会导致更高的性能损耗,因为需要切换寄存器内容,还可能刷新TLB,导致缓存失效,增加内存访问延迟。而线程切换由于共享内存空间,避免了这些开销,因此更高效。此外,引用[2]提到同进程内的线程切换只需切换私有数据,而跨进程线程切换等同于进程切换。 我需要将这些信息组织成结构清晰的回答,分点说明区别和性能影响。同时,确保使用正确的LaTeX格式,如行内公式用$...$,独立公式用$$...$$。可能还需要生成相关问题,比如优化方法、实际应用场景等。 检查是否有遗漏点,比如寄存器切换、缓存和TLB的影响,这些在引用中都有提到,需要整合到回答中。最后,确保引用标识正确对应,比如[^1]、[^2]等,并放在适当的位置。 现在,将这些整理成用户易懂的中文回答,分步骤解释区别和性能影响,同时引用相关文献支持观点。确保回答真实可靠,结构清晰,帮助用户逐步理解问题。</think>### 进程线程上下文切换的区别及性能影响 #### 一、核心区别 1. **虚拟内存空间** - **进程切换**:需要切换虚拟内存空间,导致页表缓冲(TLB)刷新,内存访问效率降低[^1][^4]。 - **线程切换**:同一进程内的线程共享虚拟内存空间,无需修改页表,TLB保持不变[^3]。 2. **资源切换范围** - **进程切换**:需保存和恢复全部资源,包括寄存器、页表、文件描述符、全局变量等[^1][^3]。 - **线程切换**:仅需切换线程私有数据(如寄存器、栈),共享资源(如虚拟内存)保持不变[^2][^3]。 3. **调度主体** - 线程是系统调度的基本单位,内核任务调度直接操作线程进程线程提供资源支持[^2][^3]。 --- #### 二、性能影响 1. **直接损耗** - 进程切换需要保存和恢复更多寄存器内容(如程序计数器、栈指针),耗时显著[^1][^4]。 - 线程切换的寄存器操作量更少,例如同进程线程切换仅需处理私有寄存器,时间开销较低[^2][^3]。 2. **间接损耗** - **缓存失效**:进程切换会导致CPU缓存(如L1/L2缓存)失效,重新加载数据增加延迟[^4]。 - **TLB刷新**:进程切换后TLB被清空,后续内存访问需重新查询页表,效率下降[^4]。 - 线程切换因共享内存空间,缓存和TLB可继续复用,间接损耗较小。 3. **数学表达示例** 假设一次进程切换耗时$T_p$,线程切换耗时$T_t$,通常满足: $$T_p = k \cdot T_t \quad (k > 1)$$ 其中$k$与资源切换量正相关[^1][^2]。 --- #### 三、典型场景对比 | **场景** | **进程切换** | **线程切换** | |------------------------|------------------------------------------|------------------------------------------| | Web服务器处理请求 | 不同用户请求分配独立进程时,频繁切换导致高延迟 | 多线程处理请求,切换开销低,吞吐量高[^2] | | 数据库事务并发 | 进程间隔离性强,但并发性能差 | 线程共享连接池,切换效率高,适合高并发[^3] | | 科学计算并行任务 | 需跨节点通信时采用多进程(如MPI) | 单节点多线程共享内存,计算效率更高[^4] | ---
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值