你注意到COM編程中“STA 單線程套間”的重入問題了嗎?

在COM編程中,COM線程模型的選擇是避免不了的。網上已有大量介紹“COM線程模型”的文章,在這裏我只想說“STA 單線程套間”並不像想象中的那麼簡單,在實際的開發中會出現“重入問題”。

“STA 單線程套間”,指的是一個線程只能建立一個套間,在線程中創建的COM對象只屬於這個套間,其他線程對此線程中COM對象的調用都必須通過代理對象串行調用。這樣,“STA 單線程套間”輕鬆解決了多線程之間的“同步問題”。

於是,我們將COM對象都採用“STA 單線程套間”,是不是就萬事大吉了呢?當然不是。爲了避免死鎖,所有的COM套間類型都支持重入,當然“STA 單線程套間”也不例外。當套間中的線程通過代理調用到其他套間中的對象的時候,調用者線程在等待此調用完成的過程中,它可以繼續處理其他的入方法請求。

 

例如,線程1中的對象a訪問線程3中的對象c,對象c又訪問線程4中的對象d。此時,線程4在處理傳入的調用,線程3在等待線程4返回,線程1在等待線程3返回。由於“STA 單線程套間”支持重入,所以,此時當線程2中的對象b發起對線程3中對象c的訪問時,就會立即執行。於是,線程3中的對象c就面臨着“重入問題”的考驗。

在一個多線程的程序中,這種“重入問題”的發生可能無處不在。如果我們忽視了這個問題的存在,那麼在後續的開發中就會遇到許多莫名其妙的問題,而且極難糾錯。因爲,我們的邏輯是對的,只是“重入問題”的發生,會將代碼的執行環境(變量或循環結構等)改變或破壞,使得程序無法再進行下去,或產生錯誤的結果。

想象一下,我們在每實現一個COM對象的方法時,都要評估這個方法會不會產生“重入問題”,如果發生“重入問題”,這個方法內的執行環境(變量或循環結構等)是否會被改變或破壞,是否需要對其他地方的代碼進行調整。如果是這樣的話,“重入問題”比“同步問題”輕鬆不了多少。

 

總之,請記住這樣一個原則:“MTA 多線程套間”考慮“同步”,“STA 單線程套間”考慮“重入”。

 

更多深入的探討請參考

COM本質論(簡體)第五章套間 5.3跨套間訪問 P193

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章