我正在阅读和学习ThreadScheduler
以及有关任务的文章并遇到了该功能ThreadPool.UnsafeQueueUserWorkItem
用于其中之一MSDN 示例 http://msdn.microsoft.com/en-us/library/system.threading.tasks.taskscheduler.aspx关于自己的ThreadSchedulers。在 MSDN 中关于 UnsafeQueueUserWorkItem 的描述 http://msdn.microsoft.com/en-us/library/system.threading.threadpool.unsafequeueuserworkitem.aspx有一个很大的警告,该功能可能是一个安全漏洞,并且它“不传播调用堆栈".
唯一的链接是QueueUserWorkItem
从名字上看,哪个似乎是“安全的对应物”?但也没有提及任何有关调用堆栈的内容。
传播堆栈到底意味着什么?在工作开始之前把它复制过来?为什么另一个线程仍然需要调用线程的堆栈?我假设他们从一个新鲜且空的堆栈开始。毕竟,当线程函数返回时,它不会继续执行调度Task的函数,对吧?
它是 CAS(代码访问安全性)的实现细节。它可以检查线程是否有足够的权限来执行操作。仅当代码在受限的安全环境中运行而不是在完全信任的情况下运行或在沙箱中运行时才重要。
完成这项工作的管道很复杂,我只能大致了解它的工作方式。 ExecutionContext 类很关键,它决定了代码运行的安全上下文。当以受限权限运行的线程启动另一个线程时,事情会变得困难。显然,其他线程需要在与原始线程相同的限制下运行。 CAS 依赖于执行堆栈遍历来发现限制的能力。这在另一个线程上很困难,它有自己的堆栈。
ExecutionContext.Capture() 方法在这里发挥着重要作用。它复制调用线程的上下文,包括进行堆栈遍历以创建所发现的安全属性的“压缩”堆栈。然后新线程使用捕获的上下文运行。
ThreadPool.UnsafeQueueUserWorkItem() 会跳过 Capture() 调用。线程池线程将使用默认执行上下文运行。
这是一种优化,Capture() 不是一个便宜的方法。对于依赖 TP 线程快速完成工作的程序来说,这一点很重要。我首先想到的是网络服务器。还有使用该方法的代码类型,例如,您会看到它在 System.Net 命名空间中的内部方法中使用。
显然它是不安全的,它不按照原始线程的 CAS 限制运行。
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)