windows核心编程指南21.pdf
![资源得分’ title=](/images/score_1.gif)
![资源得分’ title=](/images/score_1.gif)
![资源得分’ title=](/images/score_1.gif)
![资源得分’ title=](/images/score_1.gif)
![资源得分’ title=](/images/score_05.gif)
《windows核心编程指南21.pdf》由会员分享,可在线阅读,更多相关《windows核心编程指南21.pdf(6页珍藏版)》请在淘文阁 - 分享文档赚钱的网站上搜索。
1、下载第2 1章线程本地存储器有时,将数据与对象的实例联系起来是很有帮助的。例如,窗口的附加字节可以使用S e t Wi n d o w s Wo r d和S e t Wi n d o w L o n g函数将数据与特定的窗口联系起来。可以使用线程本地存储器将数据与执行的特定线程联系起来。例如,可以将线程的某个时间与线程联系起来。然后,当线程终止运行时,就能够确定线程的寿命。C/C+运行期库要使用线程本地存储器(T L S)。由于运行期库是在多线程应用程序出现前的许多年设计的,因此运行期库中的大多数函数是用于单线程应用程序的。函数 s t r t o k就是个很好的例子。应用程序初次调用 s t
2、 r t o k时,该函数传递一个字符串的地址,并将字符串的地址保存在它自己的静态变量中。当你将来调用s t r t o k函数并传递N U L L时,该函数就引用保存的字符串地址。在多线程环境中,一个线程可以调用 s t r t o k,然后,在它能够再次调用该函数之前,另一个线程也可以调用 S t r t o k。在这种情况下,第二个线程会在第一个线程不知道的情况下,让s t r t o k用一个新地址来改写它的静态变量。第一个线程将来调用 s t r t o k时将使用第二个线程的字符串,这就会导致各种各样难以发现和排除的错误。为了解决这个问题,C/C+运行期库使用了T L S。每个线程
3、均被赋予它自己的字符串指针,供s t r t o k函数使用。需要予以同样对待的其他C/C+运行期库函数还有a s c t i m e和g m t i m e。如果你的应用程序需要严重依赖全局变量或静态变量,那么 T L S能够帮助解决它遇到的问题。但是编程人员往往尽可能减少对这些变量的使用,而更多地依赖自动(基于堆栈的)变量和通过函数的参数传递的数据。这样做是很好的,因为基于堆栈的变量总是与特定的线程相联系的。标准的C运行期库一直是由许多不同的编译器供应商来实现和重新实现的。如果 C编译器不包含标准的C运行期库,那么就不值得去购买它。编程员多年来一直使用标准的 C运行期库,并且将会继续使用它
4、,这意味着s t r t o k之类的函数的原型和行为特性必须与上面所说的标准 C运行期库完全一样。如果今天重新来设计C运行期库,那么它就必须支持多线程应用程序的环境,并且必须采取相应的措施来避免使用全局变量和静态变量。在我的软件开发项目中,我总是尽可能避免使用全局变量和静态变量。如果你的应用程序使用全局变量和静态变量,那么建议你务必观察每个变量,并且了解一下它能否改变成基于堆栈的变量。如果打算将线程添加给应用程序,那么这样做可以节省大量时间,甚至单线程应用程序也能够从中得到许多好处。在编写应用程序和D L L时,可以使用本章中介绍的两种T L S方法,即动态T L S和静态T L S。但是,
5、当创建D L L时,这些T L S往往更加有用,因为D L L常常不知道它们链接到的应用程序的结构。不过,当编写应用程序时,你通常知道将要创建多少线程以及如何使用这些线程。然后就可以创造一些临时性的方法,或者最好是使用基于堆栈的方法(局部变量),将数据与创建的每个线程联系起来。不管怎样,应用程序开发人员也能从本章讲述的内容中得到一些启发。21.1 动态T L S若要使用动态T L S,应用程序可以调用一组 4个函数。这些函数实际上是 D L L用得最多的函数。图2 1-1显示了Wi n d o w s用来管理T L S的内部数据结构。图21-1 用于管理T L S的内部数据结构该图显示了系统中
6、运行的线程正在使用的一组标志。每个标志均可设置为F R E E或者I N U S E,表示T L S时隙(s l o t)是否正在使用。M i c r o s o f t保证至少T L S _ M I N I M U M _ AVA I L A B L E位标志是可供使用的。另外,T L S _ M I N I M U M _ AVA I L A B L E在Wi n N T.h中被定义为6 4。Wi n d o w s2 0 0 0将这个标志数组扩展为允许有1 0 0 0个以上的T L S时隙。对于任何一个应用程序来说,这个时隙数量足够了。若要使用动态T L S,首先必须调用T l s A
7、l l o c函数:这个函数命令系统对进程中的位标志进行扫描,并找出一个 F R E E标志。然后系统将该标志从F R E E改为I N U S E,并且T l s A l l o c返回位数组中的标志的索引。D L L(或应用程序)通常将该索引保存在一个全局变量中。这是全局变量作为一个较好选择的情况之一,因为它的值是每个进程而不是每个线程使用的值。如果T l s A l l o c在该列表中找不到 F R E E标志,它就返回 T L S _ O U T _ O F _ I N D E X E S(在Wi n B a s e.h中定义为0 x F F F F F F F F)。当T l s
8、A l l o c第一次被调用时,系统发现第一个标志是F R E E,并将该标志改为I N U S E,同时T l s A l l o c返回0。T l s A l l o c这样运行的概率是9 9%。下面介绍在另外的1%的概率下T l s A l l o c是如何运行的。当创建一个线程时,便分配一个 T L S _ M I N I M U M _ AVA I L A B L E P V O I D值的数组,并将它初始化为0,然后由系统将它与线程联系起来。如图 2 1-1所示,每个线程均得到它自己的数组,数组中的每个P V O I D可以存储任何值。在能够将信息存储在线程的P V O I D数
9、组中之前,必须知道数组中的哪个索引可供使用,这就是前面调用T l s A l l o c所要达到的目的。按照设计概念,T l s A l l o c为你保留了一个索引。如果T l s A l l o c返回索引3,那么就说明目前在进程中运行的每个线程中均为你保留了索引 3,而且在将来创建的线程中也保留了索引3。510计计第四部分动态链接库下载进程线程1引索0引索000000000000000引索1引索1引索2引索2引索3引索3引索4引索4线程2线程本地存储器的位标志:0-(TLS_MINIMUM_AVAILABLE-1)索引TLS_MINIMUM_AVAILABLE-2索引TLS_MINIMU
10、M_AVAILABLE-2索引TLS_MINIMUM_AVAILABLE-2索引TLS_MINIMUM_AVAILABLE-2若要将一个值放入线程的数组中,可以调用T l s S e t Va l u e函数:该函数将一个P V O I D值(用p v T l s Va l u e参数标识)放入线程的数组中由 d w T l s I n d e x参数标识的索引处。P v T l s Va l u e的值与调用T l s S e t Va l u e的线程相联系。如果调用成功,便返回T R U E。线程在调用T l s S e t Va l u e时,可以改变它自己的数组。但是它不能为另一个线
11、程设置 T L S值。我希望有另一个T l s函数能够用于使一个线程将数据存储到另一个线程的数组中,但是不存在这样一个函数。目前,将数据从一个线程传递到另一个线程的唯一方法是,将单个值传递给C r e a t e T h r e a d或_ b e g i n t h r e a d e x,然后该函数将该值作为唯一的参数传递给线程的函数。当调用 T l s S e t Va l u e时,始终都应该传递较早的时候调用的T l s A l l o c函数返回的索引。M i c r o s o f t设计的这些函数能够尽快地运行,在运行时,将放弃错误检查。如果传递的索引是调用T l s A l
- 配套讲稿:
如PPT文件的首页显示word图标,表示该PPT已包含配套word讲稿。双击word图标可打开word文档。
- 特殊限制:
部分文档作品中含有的国旗、国徽等图片,仅作为作品整体效果示例展示,禁止商用。设计者仅对作品中独创性部分享有著作权。
- 关 键 词:
- windows 核心 编程 指南 21
![提示](https://www.taowenge.com/images/bang_tan.gif)
限制150内