這是個比較冷門的點,是我在寫多線程之旅(2)_創建一個屬于自己的精簡線程池_線程調度策略——附C#源碼這篇文章時,發現在做線程隊列時,官方選用的是Unsafequeueuserworkitem,而不是常見的QueueUserWorkItem,所以后續我就對這兩個方法調查一番,發現資料也不多,總結一下。
首先看一下官方的定義:
來源:
https://docs.microsoft.com/zh-cn/dotnet/api/system.threading.threadpool.queueuserworkitem?view=netframework-4.8
https://docs.microsoft.com/zh-cn/dotnet/api/system.threading.threadpool.unsafequeueuserworkitem?view=netframework-4.8
將方法排入隊列以便執行,并指定包含該方法所用數據的對象。此方法在有線程池線程變得可用時執行。
參數:
WaitCallback,它表示要執行的方法。
Object,包含方法所用數據的對象。
將指定的委托排隊到線程池,但不會將調用堆棧傳播到輔助線程。
參數:
WaitCallback,表示當線程池中的線程選擇工作項時調用的委托。
Object,在接受線程池服務時傳遞給委托的對象。
看著上面的官方解釋,一如既往的迷,不用擔心是之上問題,或許是因為翻譯問題使得很難理解。
下面我用一篇文章(http://www.csframework.com/archive/2/arc-2-20110727-1759.htm)中的一段描述來解釋這個問題:
threadpool類有一個UnsafeQueueUserWorkItem方法。該方法與平時調用的QueueUserWorkItem方法非常相似。下面先簡單介 紹一下這兩個方法的區別:
當有線程試圖訪問一個受限資源(如打開一個文件)時,clr將執行一個代碼訪問安全(code access security, cas)檢查。也就是說,clr將檢查調用線程的調用堆棧中的所有程序集是否都有訪問資源的許可權限。如果有一些程序集沒有所需 的許可權限,clr將拋出一個securityexception異常。假設正在執行代碼的線程所在的程序集沒有打開文件的許可權限,那么在線程試圖打開文件時,clr將拋出一個securityexception異常。
為讓線程繼續運行,線程可以在線程池的隊列加入一個工作項,讓線程池中的線程來執行打開文件的代碼。當然這必須在擁 有合適許可權限的程序集中進行。這種“工作區”智取安全權限的現象可以允許懷惡意的代碼對受限資源進行嚴重破壞。為阻止這 種獲得安全權限的方式,QueueUserWorkItem方法內部遍歷調用線程的堆棧,并捕獲所有被授予的安全權限。然后,當線程池中的線程開始執行時,這些權限再與線程結合。因此,線程池中的線程以調用QueueUserWorkItem方法的線程相同的權限集來完成運行。
(看著是有些繞,簡單說呢,QueueUserWorkItem作為一種安全的線程池機制,其內部有一個功能,就是能遍歷調用線程池中線程的‘堆?!?,獲取堆棧中程序集所具有的安全權限。當堆棧對該線程調用時,這個線程的就繼承了調用他的堆棧內容所具有的權限。這樣就避免了權限較小的堆棧通過調用權限較大的線程,來獲取非法數據。
就好比堆棧里的內容沒有打開文件的權限,但是線程池中的線程可以打開文件,那么堆棧通過調用線程池里的線程來打開文件,從而獲取打開文件的權限。)
OK,我們再來了解一下UnsafeQueueUserWorkItem
遍歷線程的堆棧并捕獲所有的安全權限與性能緊密相關。如果希望改進受計算限制的異步操作的排隊性能,可以調用 UnsafeQueueUserWorkItem方法。該方法只將工作項加入到線程池的隊列中,而不遍歷調用線程的堆棧。最后結果是這個方法比 QueueUserWorkItem方法執行得快,但它在應用程序中打開了一個潛在的安全漏洞。僅當可以確認線程池中的線程執行的代碼不觸及受限資源時,或確信接觸這部分資源不會出現問題時,我們才可以調用unsafequeueuserwork-item方法。同樣,還需注意調用該方 法需要使securitypermission的controlpolicy標記和controlevidence標記開啟,可阻止未信任的代碼偶然或故意提升它的許可權 限。
(有了上面的鋪墊,UnsafeQueueUserWorkItem就很好理解了,為了追求效率,UnsafeQueueUserWorkItem對堆棧里的內容信任,不再去遍歷堆棧信息,讀取權限,而是直接執行。)
還有一篇文章(https://www.cnblogs.com/JeffreyZhao/archive/2009/07/22/thread-pool-1-the-goal-and-the-clr-thread-pool.html)中的一段話,提到了兩者的關聯,貼上來
我們在編寫程序的時候,可以使用ThreadPool類的兩個靜態方法:QueueUserWorkItem和UnsafeUserQueueWorkItem向CLR線程池中添加任務(一個WorkCallback委托對象),這兩個方法的區別,在于前者會收集調用方的ExecutionContext,也就是保留了的當前線程的執行信息(如認證或語言文化等),使任務最終會在“創建”時刻的環境中執行2——后者就不會。因此,如果比較兩個方法的絕對性能,Unsafe方法會略勝一籌。但是平時還是建議使用QueueUserWorkItem方法,因為保留執行上下文會避免很多麻煩事情,且這點性能損耗其實算不上什么。
這段話表述不是很清楚,但大概意思也表明了QueueUserWorkItem方法在處理線程時會做更多的信息評判,更加安全。而相比之下UnsafeQueueUserWorkItem的執行效率更高。
本文由 貴州做網站公司 整理發布,部分圖文來源于互聯網,如有侵權,請聯系我們刪除,謝謝!
網絡推廣與網站優化公司(網絡優化與推廣專家)作為數字營銷領域的核心服務提供方,其價值在于通過技術手段與策略規劃幫助企業提升線上曝光度、用戶轉化率及品牌影響力。這...
在當今數字化時代,公司網站已成為企業展示形象、傳遞信息和開展業務的重要平臺。然而,對于許多公司來說,網站建設的價格是一個關鍵考量因素。本文將圍繞“公司網站建設價...
在當今的數字化時代,企業網站已成為企業展示形象、吸引客戶和開展業務的重要平臺。然而,對于許多中小企業來說,高昂的網站建設費用可能會成為其發展的瓶頸。幸運的是,隨...
寫表單的時候有個value屬性,是表示什么呢?Value是表單控件傳遞給處理程序的值。例如,這是一個文本框。其值為“請在此處填寫用戶名”,即文本框。原文是“請在這里填寫用戶名”男女這是兩個單選按鈕。如果在表單提交后選擇“男”,則提交的值就是值,即表單提交后選擇“男”,反之亦然...
蘋果手機下載鈴聲教程?1、打開一個音樂App,比如酷我,在播放界面再點擊三個點蘋果14怎么下載歌曲?建議使用USB轉換器將蘋果手機與移動設備直接連接,然后再然后打開蘋果手機的音樂播放器,在搜索框中再輸入自己就是喜歡的歌曲,直接點擊下載,將其存儲的目錄真接網頁到USB連接的移動設備,直接下載能完成之后即可存貯在移動設備中能夠完成去下載。iphone如何把音樂導入本地?1.關閉Apple Music進...
百米生活100msh的登陸密碼多少?1)首先,打開界面,知道賬單是個人票據。然后點擊“三橫”功能鍵的左上角。中國2)進入功能界面后,點擊“三橫”功能鍵上的“設置”按鈕,進入左側的設置界面,找到密碼保護設置界面,然后按密碼保護右側的“開關”。3)點擊開關,顯示密碼設置界面,輸入自己的密碼。4)設置密碼后,將打開密碼保護。打開時,退出便箋,必須輸入密碼才能再次登錄。因此,人們不怕看到自己的隱私已知的筆...