我一直在考虑为我的应用程序添加线程化程序以加快执行速度,但问题是我真的不知道如何使用线程,或者什么被认为是“线程安全”。例如,游戏引擎如何在其渲染过程中使用线程,或者在什么情况下线程只被认为只是一个障碍?有人可以指出一些资源,以帮助我了解更多或在这里解释?
答案 0 :(得分:32)
这是一个非常广泛的话题。但如果我对线程一无所知,那么我想知道的事情是什么:
它们是在“并行”发生的单个进程中的执行单元 - 这意味着处理器中的当前执行单元快速切换。这可以通过不同的方式实现。切换称为“上下文切换”,并且存在与此相关的一些开销。
他们可以分享记忆!这是可能发生问题的地方。我将在后面的章节中更深入地讨论这个问题。
并行化应用程序的好处是使用机器不同部分的逻辑可以同时发生。也就是说,如果您的进程的一部分受I / O限制并且其中一部分受CPU限制,则I / O密集型操作不必等到CPU密集型操作完成。如果您有多核处理器,某些语言也允许您同时运行线程(因此也可以并行化CPU密集型操作),但情况并非总是这样。
线程安全意味着没有竞争条件,这是用于在您的流程执行取决于时间时发生的问题的术语(您不想要的事情)依靠)。例如,如果线程A
和B
都递增共享计数器C
,您可以看到A
读取C
的值的情况,然后B
读取C
的值,然后A
用C
覆盖C+1
,然后B
用{C
覆盖C+1
1}}。请注意,C
实际上只增加一次!
避免竞争条件的几种常见方法包括同步,它排除了对共享状态的相互访问,或根本没有任何共享状态。但这只是冰山一角 - 线程安全是一个相当广泛的话题。
我希望有所帮助!理解这是一个非常快速的介绍,需要一些学习的东西。我建议用你喜欢的语言找到一个关于多线程的资源,无论发生什么,并给它一个彻底的阅读。
答案 1 :(得分:2)
关于线程你应该知道四件事。
线程就像进程一样,但它们共享内存。
线程通常具有硬件,操作系统和语言支持,这可能使它们比进程更好。
线程需要支持许多繁琐的小东西(比如锁和信号量),因此它们不会将它们共享的内存变为不一致的状态。这使得它们有点难以使用。
锁定不是自动的(用我所知的语言),所以你必须非常小心它们(隐式)共享的内存。
答案 2 :(得分:1)
线程不会加速应用程序。算法加速了应用程序。如果合适,线程可以用在算法中。
答案 3 :(得分:1)
有人可能会更好地回答这个问题,但是线程的目的是让后台处理不会冻结用户界面。你不想停止接受键盘输入或鼠标输入,并告诉用户,“只是片刻,我想完成这个计算,它只需要几秒钟。” (然而,令人惊讶的是商业计划多少次这样做。
就线程安全而言,它意味着一个没有内部保存状态的函数。如果它确实你没有多个线程同时使用它。
就线程编程而言,您只需要开始执行它,然后您将开始遇到线程编程特有的各种问题,例如,对数据的同时访问,在这种情况下,您必须决定使用某些同步方法,例如作为关键部分或互斥体或其他东西,每个人的行为都有细微差别。
只要进程和线程(您没有问过)进程之间的差异是操作系统级实体,而线程与程序关联。在某些情况下,您的程序可能想要创建一个进程而不是一个线程。
答案 4 :(得分:1)
线程只是一种同时执行多个事物的方式(假设它们运行的平台能够并行执行)。线程安全很简单(好吧,没有什么线程真的很简单)确保线程不会以有害的方式相互影响。
通常,由于可能产生的多重性能影响和复杂性问题,您不太可能看到系统使用多个线程在屏幕上呈现图形。但是,与状态管理(或AI)相关的其他任务可能会被移动到单独的线程中。
答案 5 :(得分:1)
线程的第一条规则:不要线程化。第二条线程规则:如果你必须违反第一条规则......不要。第三条规则:好的,你必须使用线程,所以在继续进行陷阱之前,要了解锁定和常见的线程问题,例如死锁和活锁。
了解线程不会加速任何事情,它只对后台长时间运行的进程有用,允许用户可以对应用程序执行其他操作。如果您必须允许用户在应用程序在后台执行其他操作时与应用程序进行交互,例如轮询套接字或等待应用程序中其他位置的异步输入,那么您可能确实需要线程化。
Effective Java和Clean Code中的线程部分是对线程及其陷阱的良好介绍。
答案 6 :(得分:1)
由于问题标记为'Java',我假设您熟悉Java,在这种情况下这是一个很好的入门教程 http://java.sun.com/docs/books/tutorial/essential/concurrency/
答案 7 :(得分:1)
Orm,这是个很好的问题。我认为所有认真的程序员都应该了解线程,最终你将至少考虑使用它们,并且你真的希望在它发生时做好准备。并发错误可能非常微妙,避免它们的最佳方法是知道哪些习语是安全的(-ish)。
我强烈建议您花些时间阅读Doug Lea撰写的“ Java并行编程:设计原则和模式”一书: http://gee.cs.oswego.edu/dl/cpj/
Lea不仅花时间教你概念,而且还向你展示使用并发编程原语的正确和错误方法(在Java中,但也有助于使用共享内存锁定/信令风格的任何其他环境)并发)。最重要的是,他教导了对并发编程难度的尊重。
我应该补充一点,这种并发编程风格是最常见但不是唯一的方法。还有消息传递,这更安全,但迫使您以不同方式构建算法。
答案 8 :(得分:1)
由于原帖非常广泛,并且还标有C ++,我认为以下指针是相关的:
Boost Thread Library的维护者Anthony Williams一直致力于一本名为“C ++ Concurrency in Action”的书,你可以找到here的描述。第一章(介绍性)章节以pdf格式here免费提供。
另外,Herb Sutter(其中包括他的“Exceptional C ++”系列)已经写了一本名为“Effective Concurrency”的书,其中许多文章都以草稿形式here提供。
答案 9 :(得分:0)
有一本好书, Java Concurrency in Practice ,http://www.javaconcurrencyinpractice.com/。