社区
C++ 语言
帖子详情
还是线程局部存储区问题???
xuxian02092213
2008-11-12 08:03:54
windows核心变成中 线程局部存储区章节讲述了一个线程都有个 位标志,还有个是每个线程都有个PVOID数组,且他们的大小
是64(在WinNT上,但是可以动态扩展),我疑惑的是:当一个线程创建了,现在马上调用了TlsAlloc()函数,这个时候返回了4
(假设的),也就是说现在这个线程中的PVOID数组没有存放任何数据,现在要调用TlsSetValue()函数,那么数据存放在数组的那
个位置?是从头开始位置,还是数组的第五个单元?
...全文
331
26
打赏
收藏
还是线程局部存储区问题???
windows核心变成中 线程局部存储区章节讲述了一个线程都有个 位标志,还有个是每个线程都有个PVOID数组,且他们的大小 是64(在WinNT上,但是可以动态扩展),我疑惑的是:当一个线程创建了,现在马上调用了TlsAlloc()函数,这个时候返回了4 (假设的),也就是说现在这个线程中的PVOID数组没有存放任何数据,现在要调用TlsSetValue()函数,那么数据存放在数组的那 个位置?是从头开始位置,还是数组的第五个单元?
复制链接
扫一扫
分享
转发到动态
举报
写回复
配置赞助广告
用AI写文章
26 条
回复
切换为时间正序
请发表友善的回复…
发表回复
打赏红包
ithzhang
2011-10-08
打赏
举报
回复
现总结下让以后对这点不清楚的同学能理解。
所谓的标志数组是进程共享的。
他是一个数组。有TLS_MINIMUM_AVILABLE个状态。
另外
每个线程都有一个数组
。(这一点很容易疑惑)
这些数组也是TLS_MINIMUM_AVILABLE项。
每个状态位对应线程内数组的每一项。
当在线程内调用TlsAlloc的时候,系统会遍历状态位数组,
查找状态为FREE或INUSE的项
然后返回下标。在函数返回之前函数会遍历所有线程,将所有线程的该项都清零。
在本线程的数组中,这个下标标志的一项就分配给了他。他就可以使用了。
其他线程各自含有一个数组,只是
他们只能使用分配给自己的那些项
。分配给其他线程的项他们不能使用。
另外要注意由于每个线程都含有一个数组,但是各个数组都是不相干的。虽然线程可以调用TlsSetValue修改并不是分配给自己的项,但是并不影响其他线程。
ithzhang
2011-10-08
打赏
举报
回复
三年后我也疑惑与这个问题。但是看了楼上的各位的回答清楚了很多。
herman~~
2008-11-17
打赏
举报
回复
学习
cnzdgs
2008-11-15
打赏
举报
回复
系统会根据需要扩充空间,当不能再扩充时会返回失败(TLS_OUT_OF_INDEXES)。
LZ对TLS的用法理解有误,一般应该由主线程来调用TlsAlloc和TlsFree,将索引值通过全局变量/数组或其它形式传递给各个线程,而不是各个线程自己来分配,线程只使用TlsSetValue和TlsGetValue来存取数据。
lzr4304061988012
2008-11-15
打赏
举报
回复
TLS系统有点像是在实现静态局部变量,如果你用全局变量的话就要考虑同步的问题,但是TLS由于是每个线程都有自己的静态存储数据,而不是与其他线程共享,
所以不用考虑.
xuxian02092213
2008-11-15
打赏
举报
回复
恩~~~~谢谢楼上几位的高见
还有个问题,线程局部存储区中的元素,仅仅是共本线程使用的,而其他的线程则是不能够去访问使用,那么这又有什么独特的用
处??我完全可以个全局变量来完成啊,或者是其他的方法,但为什么非弄个TLS出来呢???全局变量要尽量的少使用,可是书
上却没有说为什么要少使用,我想问问为什么???
hhyttppd
2008-11-14
打赏
举报
回复
[Quote=引用 10 楼 xuxian02092213 的回复:]
上面的问题有点问题啊,是一个进程都会有一个标志位数组,大小为64,每个线程都有一个指针数组,是PVOID类型的,默
认也是64的数组。。。对于我的提问,上面的几位高手说是下标为 4 的地方。。。我们再来做个假设啊,就是什么呢,
有几个线程,第一个线程使用了 第0 号索引,那么第一个线程的PVOID数组的第 0 单元被使用,第二线程使用TLS的使用
后,那么返回的索引号是非 0 的,假设是 1号,那么第二个线程将使用 PVOID 的…
[/Quote]
你这么理解岂不是认为进程只创建不超过64个线程?
xuxian02092213
2008-11-14
打赏
举报
回复
上面的问题有点问题啊,是一个进程都会有一个标志位数组,大小为64,每个线程都有一个指针数组,是PVOID类型的,默
认也是64的数组。。。对于我的提问,上面的几位高手说是下标为 4 的地方。。。我们再来做个假设啊,就是什么呢,
有几个线程,第一个线程使用了 第0 号索引,那么第一个线程的PVOID数组的第 0 单元被使用,第二线程使用TLS的使用
后,那么返回的索引号是非 0 的,假设是 1号,那么第二个线程将使用 PVOID 的第 1 个单元。。按上面的所说,暗含
第二个线程就不能使用 第 0 个单元,第三个线程就不能使用 第0 、1 个单元、、、、
最后一个线程使用TLS的是由,前面 64 个单元都被使用了,最后一个返回的索引肯定不是0~63 ,那么最后一个使用什么
呢,微软动态添加索引标志位又有什么作用呢???书上说的,只是动态添加标志位数组大小,而不会添加线程中PVIOD 数
组大小。还请各位高手赐教
lzr4304061988012
2008-11-14
打赏
举报
回复
假如确实有1000个标志位,而且这1000个都不是空的,TlsAlloc返回1000,该线程的PVOID要增长那么大,这个不是恶心增长,你要多少我有的话,为什么不给
你分配呢?
另外有一个TlsFree释放用完了的索引.这样用过了会释放。
xuxian02092213
2008-11-14
打赏
举报
回复
???
这样看 。。。。 假设进程中使用了 1000个 标志位,一个新线程创建了,现在它要用TLS ,那么TlsAlloc返回的 是
1000,这个时候这么办啊???他会将PVOID数组增加到1000(或者说是是1024)吗???这算不算是一个恶性增长啊,明明只
要用一个TLS元素,却分配了 那么多的TLS单元??
PS: 对我来讲 64 确实一个很特殊的数组,在网络编程中,在核心编程中,(在Linux中也是)都遇到过 64这个数组,到底是这
么来的我也不是很清楚
xiaopoy
2008-11-14
打赏
举报
回复
纯帮顶。
PS:64是一个很特殊的数字嘛?必须要不大于64?
cnzdgs
2008-11-14
打赏
举报
回复
超过64时,会再分配一个4KB的数组。
lzr4304061988012
2008-11-14
打赏
举报
回复
是这样的:TlsAlloc函数在 标志位数组中找 标示位为FREE的槽,如果不存在空槽,就申请更多的空间,
TlsSetValue 然后在指定的线程中找这个索引号之前,它会先判断这个索引号是否大于数组计数 nCount,
如果大于,申请更多空间,再放入LPVOID。
lzr4304061988012
2008-11-14
打赏
举报
回复
也会增加PVOID的数组大小.
xuxian02092213
2008-11-14
打赏
举报
回复
BOOL TlsSetValue(DWORD dwTlsIndex, LPVOID lpTlsValue);
这个函数是把lpTlsValue保存到当前线程的TLS数组中下标为dwTlsIndex的元素中,各个线程是相互独立的,每个线程都有自己的TLS数组。例如,所有线程都可以将第4个元素设置成任意一个值,然后再取出,各个线程取出的都是自己所设置的值,与其它线程无关。
这点是可以说通的,问题就是一个进程下面只有一个
标志位数组
,他标示位FREE或
者是INUSE,在线程中调用TlsAlloc的时候,他会返回一个标志位索引,并将其标志设为INUSE,这个索引被此线程使用,以后在
这个标志位未设成FREE之前,任何线程都不可以使用这个标志位。。。。假设刚刚返回的索引号是 4,再假设这个进程有100个线
程(每个线程都要使用TLS),那么只有一线程的使用过 下标为 4 的PVOID数组单元,其他的都没有使用,而且这个样子,如果
TlsAlloc返回了大于 64 的时候,那么会怎么样呢,系统会动态增加
标志位数组
大小,但是也会增
加PVOID数组大小吗?返回了大于 64值的时候,PVOID 数组不就越界了吗???????
cnzdgs
2008-11-14
打赏
举报
回复
BOOL TlsSetValue(DWORD dwTlsIndex, LPVOID lpTlsValue);
这个函数是把lpTlsValue保存到当前线程的TLS数组中下标为dwTlsIndex的元素中,各个线程是相互独立的,每个线程都有自己的TLS数组。例如,所有线程都可以将第4个元素设置成任意一个值,然后再取出,各个线程取出的都是自己所设置的值,与其它线程无关。
cyj626
2008-11-14
打赏
举报
回复
学习
帅得不敢出门
2008-11-13
打赏
举报
回复
up
jeff_nie
2008-11-13
打赏
举报
回复
MARK.
Longinc
2008-11-13
打赏
举报
回复
UP
加载更多回复(6)
理解
线程
局部
存储
区
本文深入探讨了
线程
局部
存储
(TLS)的概念及其在C/C++多
线程
程序中的应用。介绍了TLS的两种类型:动态TLS和静态TLS,详细讲解了动态TLS的实现机制,包括TlsAlloc、TlsSetValue、TlsGetValue和TlsFree等函数的使用,以及静态TLS的声明方式。阐述了TLS在解决多
线程
环境下全局变量和静态变量
问题
上的作用。
线程
局部
存储
线程
局部
存储
(TLS)是多
线程
编程重要技术,可避免竞态条件和数据不一致。不同操作系统实现有别,Linux依赖POSIX标准,Windows通过TEB和索引表管理。C++可用关键字声明。Java和Python也有类似特性,通过不同方式实现
线程
间变量隔离。
【Linux】
线程
分离 |
线程
库 | C++调用
线程
|
线程
局部
存储
文章讨论了
线程
分离的原因,如避免主
线程
阻塞,防止内存泄漏。通过`pthread_detach`函数实现
线程
分离,分离后的
线程
无法再被join。
线程
库的作用在于管理
线程
,先描述
线程
属性(如
线程
局部
存储
),再组织
线程
执行。在C++中,可以使用`
`头文件创建多
线程
,并需要链接pthread库。
线程
局部
存储
确保了
局部
变量在
线程
间的独立性,而全局变量默认是共享的,但通过`__thread`编译选项可以创建
线程
私有的全局变量。
TLS
线程
局部
存储
本文深入探讨
线程
局部
存储
(TLS)的概念,包括动态和静态TLS的原理与应用。通过实例展示TLS如何解决多
线程
间变量同步
问题
,实现
线程
绑定数据。
10.
线程
局部
存储
本文介绍了Windows和Linux系统的
线程
局部
存储
(TLS)原理与使用方法,包括TLS的分配、访问、释放,以及C++11的`thread_local`关键字的应用。着重讨论了如何在多
线程
环境下安全高效地使用
线程
局部
存储
来
存储
和共享数据。
C++ 语言
65,211
社区成员
250,514
社区内容
发帖
与我相关
我的任务
C++ 语言
C++ 语言相关问题讨论,技术干货分享,前沿动态等
复制链接
扫一扫
分享
社区描述
C++ 语言相关问题讨论,技术干货分享,前沿动态等
c++
技术论坛(原bbs)
社区管理员
加入社区
获取链接或二维码
近7日
近30日
至今
加载中
查看更多榜单
社区公告
请不要发布与C++技术无关的贴子
请不要发布与技术无关的招聘、广告的帖子
请尽可能的描述清楚你的问题,如果涉及到代码请尽可能的格式化一下
试试用AI创作助手写篇文章吧
+ 用AI写文章