首页 诗词 字典 板报 句子 名言 友答 励志 学校 网站地图
当前位置: 首页 > 教程频道 > 开发语言 > 编程 >

【Windows核心编程学习札记】线程

2012-11-22 
【Windows核心编程学习笔记】线程一、什么是线程 线程,有时候被称为轻量级进程(LightWeight Process,LWP),是

【Windows核心编程学习笔记】线程

一、什么是线程

 

线程,有时候被称为轻量级进程(LightWeight Process,LWP),是程序执行的最小单元。一个标准的线程由线程ID,当前指令指针(PC),寄存器集合和堆栈组成。另外,线程是进程中的一个实体,是被系统独立调度和分派的基本单位,线程自己不拥有系统资源,只拥有一点在运行中必不可少的资源,但它可与同属一个进程的其它线程共享进程所拥有的全部资源。

线程由两部分组成:

(1)线程的内核对象,操作系统用它来管理线程以及存放线程统计信息。

(2)线程栈,用于维护线程执行时所需的所有函数参数和局部变量。

 

进程从来不执行任何东西,它只是一个线程的容器。线程必然是在某个进程的上下文中创建的,而且会在这个进程内部“终其一生”。这意味着要在其进程的地址空间内执行代码和处理数据。所以,假设一个进程上下文中有两个以上的线程在运行,这些线程将共享一个地址空间。这些线程可以执行同样的代码,可以处理相同的数据。此外,这些线程还共享内核对象,因为句柄表示针对每一个进程的,而不是针对每一个线程。

相较于线程,进程所使用的系统资源更多。其原因在于地址空间。为一个进程创建一个虚拟的地址空间需要大量系统资源。系统中会发生大量的记录活动,而这需要大量内存。而且,由于exe和dll文件要加载到一个地址空间,所以还需要用到文件资源。另一方面,线程使用的资源要少很多。事实上,线程只有一个内核对象和一个栈,几乎不涉及记录活动。

 

二、线程的创建

 

每次初始化进程时,系统会创建一个主线程。对于用Microsoft C/C++编译器生成的应用程序,这个线程会执行C/C++运行库的启动代码,后者调用入口点函数(_tmain或_tWinMain),并继续执行,直至入口点函数返回C/C++运行库的启动代码,后者最终调用ExitProcess。对于许多应用程序来说,这个主线程是i应用程序唯一需要的线程,但是进程也可以创建额外的线程来帮助他们完成自己的工作。

 

每个线程都有一个入口点函数,这是线程执行的起点。形式如下:


对CreateThread函数的一个调用导致系统创建一个线程内核对象。该对象的最初的使用记数为2.(除非线程终止,而且从CreateThread返回的句柄被关闭,否则线程的内核对象不会被销毁)。该内核对象的其他属性也被初始化:暂停记数被设为1,退出代码被设为STILL_ACTIVE,而且对象被设为未触发状态。

一旦创建了内核对象,系统就分配内存,供线程的堆栈使用。此内存时从进程的地址空间内分配的,因为线程没有自己的地址空间。然后系统将两个值写入新线程的堆栈的最上端(注意:线程堆栈始终是从高位地址到地位内存地址构建的),写入线程堆栈第一个值是传给CreateThread函数的lpParameter参数值。紧接在下方的是传给这个函数的lpStartAddress值。

每个线程都有自己的一组CPU寄存器,成为线程的上下文(context)。上下文反应了当线程上一次执行时,线程的CPU寄存器状态。线程的CPU寄存器全部保存在一个CONTEXT结构中,这个结果保存在线程的内核对象中。

指令指针寄存器和栈指针寄存器是线程上下文中最重要的两个寄存器。这两个地址标识的内存都位于线程所在进程的地址空间中。当线程内核对象被初始化的时候,CONTEXT结果的堆栈指针继承前辈设为lpStartAddress在线程堆栈中的地址。而指令指针寄存器被设为函数RtlUserThreadStart的地址。

 

热点排行