2013-06-04 36 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

相關問題