我知道如果有人使用很多廣泛的範圍狀態,這是一個壞主意,但如何不變的計算和高度局部副作用呢?爲什麼多線程環境被認爲是有害的?
回答
調試多線程代碼很困難。真的很難。
雖然緩解狀態,適當的設計可以減少這種困難,但它仍然比調試單線程代碼更困難。
因此,多線程的多線程是設計病理。
這就是說,有很多情況下使用> 1線程是正確的決定。
爲了過於簡化,Erlang和Haskell等函數式語言圍繞着多線程應用程序在消除副作用時非常安全的概念而構建。你應該閱讀這些。另外,一般來說,沒有共享狀態的多線程應用程序是非常安全的。
http://en.wikipedia.org/wiki/Haskell_%28programming_language%29
http://en.wikipedia.org/wiki/Erlang_%28programming_language%29
多線程編程不被認爲是有害的,而是非常困難的工作要做正確的。有許多事情從第一眼就看不到,可能會導致死鎖和競賽狀況。
不可變的計算和函數式編程是處理多線程編程複雜性的一種方法。隨着今天多核系統無處不在,人們普遍認爲程序員不應該獨自在多線程環境中編程,而應該依賴框架或庫。例如,在.NET環境中,並行擴展將成爲4.0版本框架的一部分。
很多人都接近多線程,就好像它是性能問題的銀彈。舉例來說,做一個「計算密集型操作」的相對常見的情況,操作是無關緊要的。
一個常見的誤解是,通過多線程操作我們可以加快速度。具體情況要複雜得多。這取決於流程是什麼以及流程中有多少「等待」。如果這個過程非常緊張,把它放到一個多線程環境中最好稍微加快一點,而且在大多數情況下它會使速度變慢。
還有管理狀態,管理線程交互以及由線程引入的確定性問題。
當然列表從那裏繼續。
您在單線程程序中使用的算法可能很容易縮放到多個線程。例如,如果您想要執行多線程圖像壓縮,某些格式固有地平鋪,因此您可以爲每個圖塊分配一個線程,但是例如Lossless JPEG基於最近鄰點預測,所以最後一個像素可能依賴於它們之間的所有值,因此該算法不適合在多個線程之間進行劃分。
多線程在C++中是困難的,因爲(除了別的以外):
- 變量的每一個修改必須臨界區之內完成。從源代碼的靜態分析很難看出哪個變量需要這種鎖定。
- 關鍵部分的範圍必須足夠小以避免性能問題,但對每個變量使用單獨的關鍵部分通常是不可能的,因爲必須同時更新多個變量。
- 嵌套關鍵部分必須分層使用。但是,可以在編譯時插入的工具不存在。
- 發生錯誤時,由於計時問題,通常很難重現。因此,代碼難以測試並且難以調試。
- 因爲C++沒有內置的線程支持,所以沒有手動設置斷點就不可能進行異步函數調用。
- 1. (爲什麼)被認爲是有害的CSS星形選擇器?
- 2. 'make install'被認爲是有害的嗎?
- 3. 字母O被認爲是有害的?
- 4. 使用「break」打破「for」循環被認爲是有害的?
- 5. 爲什麼OCaml的線程被認爲是「不夠」?
- 6. SICP練習3.8 - 爲什麼程序有效? (我認爲這是對環境)
- 7. PKG_CHECK_MODULES認爲有害?
- 8. NSCopyObject認爲有害?
- 9. 什麼被認爲是超載主線程?
- 10. 爲什麼'\\'被認爲是int?
- 11. sudo有不同的環境,爲什麼?
- 12. Perl:爲什麼我的環境變量沒有被設置?
- 13. 風格認爲有害?
- 14. PHP sprintf認爲有害?
- 15. mod_wsgi + apache沒有多線程,爲什麼?
- 16. 爲什麼使用TransactionScope的默認構造函數有害?
- 17. Mac OSX? Linux呢? X?侏儒? KDE?爲什麼osx被認爲是linux,爲什麼它不被認爲是linux?
- 18. 爲什麼不是多線程循環更快?
- 19. 什麼被認爲是C++語句?
- 20. Syntactic Sugar爲什麼有時被認爲是壞事?
- 21. 爲什麼ostringstream在多線程環境下無法正常工作
- 22. 這個線程環境結構是做什麼的?它的目的是什麼?
- 23. 在多線程環境
- 24. 實現多線程環境
- 25. 多線程和多處理器環境對線程有用嗎?
- 26. 什麼被認爲是一個單獨的ASP.NET應用程序?
- 27. 這是線程代碼做我認爲是什麼?
- 28. 爲什麼用對象編程不被認爲是程序性的?
- 29. 還有什麼被認爲是Android的沉重任務?
- 30. 在多線程環境中使用什麼;向量或ArrayList
挑剔 - 對SHARED變量的每個修改都需要鎖定或原子操作。我可以通過調用InterlockedIncrement或InterlockedDecrement來修改Win32中的共享計數器,這是原子級的,即不會被搶佔,同樣我可以在Win32上調用InterlockedCompareExchange。兩種方法即鎖和原子都有它們的缺陷! – zebrabox 2009-12-22 13:34:51
@zebrabox:當然,如果變量可以被多個線程修改,變量只需要被鎖定。 – 2009-12-22 14:18:49