首页
学习
活动
专区
工具
TVP
发布
社区首页 >问答首页 >.NET中GC期间线程的安全暂停

.NET中GC期间线程的安全暂停
EN

Stack Overflow用户
提问于 2010-12-12 02:54:52
回答 1查看 2.1K关注 0票数 9

.NET中的线程在GC期间暂停。如何通过CLR安全地暂停线程?像Win32 SuspendThread API这样粗暴地停止线程会有什么风险?

EN

回答 1

Stack Overflow用户

发布于 2010-12-12 03:25:29

通常,线程1可以安全地暂停线程2,这是通过设置“请立即挂起”标志来实现的,该标志保证线程2中的执行代码在限定的时间段内进行测试,并且稍后在其执行中将其自身挂起一个安全点。

在.NET CLR中(以前是这样),线程可以处于协作GC模式或抢占模式。在协作模式下,例如在运行托管代码方法时,线程偶尔会显式地检查它是否应该让步。

相反,在抢占模式中,例如当运行p-调用本机代码时,并且有时当在CLR本身(MSCORWKS.DLL等)中时,另一线程(包括需要GC的另一clr线程)可以在任何指令边界处单方面地挂起第一线程。

事实上,这些是可以组合在一起的。如果抢先模式线程返回到协作模式(然后测试该标志并挂起其线程),则CLR可以设置“请立即挂起”标志,然后等待一段时间。如果在等待之后,抢占模式线程仍然没有挂起,CLR (在另一个线程上)可能会单方面挂起它。

在协作模式下运行.NET方法时,生成的本机代码依赖于协作模式的非抢占保证来最有效地操作对象内存(GC堆等)。如果您在外部“粗暴地”挂起协作GC线程在其执行过程中的任意点,可能会使对象内存或其他CLR内部处于一种可能不适合正确的垃圾收集周期或其他CLR操作的状态。但这在实践中从来没有发生过,因为这不是协作模式线程暂停的方式。

(显然有一些极端的情况,例如当协作模式线程完成其OS线程调度程序量程,并且OS上下文将该核心切换到其他线程时。由于线程不再运行,因此它不会轮询让步标志,也不会立即放弃。我不记得在这种情况下会发生什么-- CLR是否必须等待,直到它被重新调度、测试标志并放弃,或者它是否无论如何都会挂起线程,然后检查它的IP,看看它是否在安全的地方。有人吗?)

我相信这是在SSCLI (转子)内部描述的。

合乎道理?

黑客快乐!

票数 5
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/4418356

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档