我知道如果有人使用很多广泛的范围状态,这是一个坏主意,但如何不变的计算和高度局部副作用呢?为什么多线程环境被认为是有害的?
回答
调试多线程代码很困难。真的很难。
虽然缓解状态,适当的设计可以减少这种困难,但它仍然比调试单线程代码更困难。
因此,多线程的多线程是设计病理。
这就是说,有很多情况下使用> 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. 为什么邪恶的合并被认为是有害的?
- 2. (为什么)被认为是有害的CSS星形选择器?
- 3. 字母O被认为是有害的?
- 4. SQLite“COUNT(*)”被认为是有害的?
- 5. 'make install'被认为是有害的吗?
- 6. 使用“break”打破“for”循环被认为是有害的?
- 7. org.hibernate.Session.clear()认为是有害的?
- 8. 为什么OCaml的线程被认为是“不够”?
- 9. SICP练习3.8 - 为什么程序有效? (我认为这是对环境)
- 10. 为什么类实例值在多线程环境中被损坏?
- 11. NSCopyObject认为有害?
- 12. PKG_CHECK_MODULES认为有害?
- 13. 为什么线程被多次创建?
- 14. C++ 11认为是什么“线程”?
- 15. 什么被认为是超载主线程?
- 16. 为什么Redis被认为是CP?
- 17. 为什么'\\'被认为是int?
- 18. sudo有不同的环境,为什么?
- 19. 分配jQuery功能被认为是有害的?
- 20. 为什么单线程java程序有这么多的线程?
- 21. Perl:为什么我的环境变量没有被设置?
- 22. WebLogic(10.3.5)线程池和阻塞线程 - 什么被认为是持续使用?
- 23. 为什么静态字段通常被认为是线程安全的?
- 24. 生产环境中的多线程代码中的Thread.Sleep有哪些危害
- 25. PHP sprintf认为有害?
- 26. 风格认为有害?
- 27. atexit认为有害吗?
- 28. 为什么不是numpy.mean多线程?
- 29. 为什么daemon线程在其环境被破坏时不会死亡?
- 30. REST:HTTP 303是否被认为对异步操作有害?
挑剔 - 对SHARED变量的每个修改都需要锁定或原子操作。我可以通过调用InterlockedIncrement或InterlockedDecrement来修改Win32中的共享计数器,这是原子级的,即不会被抢占,同样我可以在Win32上调用InterlockedCompareExchange。两种方法即锁和原子都有它们的缺陷! – zebrabox 2009-12-22 13:34:51
@zebrabox:当然,如果变量可以被多个线程修改,变量只需要被锁定。 – 2009-12-22 14:18:49