2013-06-04 35 views
13

我正在阅读和学习ThreadScheduler以及任务周围的文章,并且遇到了有关自己的ThreadSchedulers的MSDN examples之一中使用的函数ThreadPool.UnsafeQueueUserWorkItem。在MSDN description about UnsafeQueueUserWorkItem有一个很大的警告,该功能可能是一个安全漏洞,并且它“不传播调用堆栈”。UnsafeQueueUserWorkItem和“传播调用堆栈”的意思是什么?

唯一的链接是QueueUserWorkItem哪个 - 从名字 - 似乎是“安全对手”?但没有提及任何有关调用堆栈的内容。

传播堆栈究竟意味着什么?工作开始前复制它?为什么另一个线程仍然需要调用线程的堆栈?我会假设他们从一个新的空栈开始。毕竟,当线程函数返回时,它不会继续执行调度Task的函数,对吧?

回答

16

这是CAS,Code Access Security的实现细节。它可以检查线程是否有足够的权限来执行操作。如果代码在受限制的安全环境中运行,而不是在完全信任或沙箱中运行,则这一点很重要。

使这项工作的管道是复杂的,我只能近似它的工作方式。 ExecutionContext类是关键,它决定了代码运行的安全上下文。当一个以限制权限运行的线程启动另一个线程时,事情会变得很困难显然,其他线程需要运行与原始线程相同的限制。 CAS取决于能够执行堆栈走动来发现限制。这在另一个线程上很困难,它有自己的堆栈。

ExecutionContext.Capture()方法在这里执行重要的角色。它会创建调用线程的上下文的副本,包括进行堆栈遍历以创建发现的安全属性的“压缩”堆栈。新线程随后与捕获的上下文一起运行。

ThreadPool.UnsafeQueueUserWorkItem()跳过Capture()调用。线程池线程将使用默认的执行上下文运行。

这是一个优化,Capture()不是一个便宜的方法。它依赖于TP线程来快速完成任务。一个Web服务器跳转。也是使用该方法的代码类型,例如,您可以在System.Net命名空间的内部方法中看到它。

显然这是不安全的,它不会与原始线程的CAS限制一起运行。

+1

啊,我明白了。很有意思。现在......当不在任何安全环境下运行时,它是否会有性能差异? – Imi

+0

不是它的工作方式,CAS检查总是执行。堆栈走线具有取决于堆栈深度的固定成本。 “成本”是一个大词,我们在这里讨论的是几微秒。这完全没有关系,直到您每秒运行数千* TP线程请求为止。 –

+0

_we're在这里谈论少量微秒_哇..感谢评论。然后我更好地描述我的自定义线程调度程序原型。我明确地说,不能在“微秒”的范围内生活。 – Imi

相关问题