【问题标题】:Can Someone Explain Threads to Me? [closed]有人可以向我解释线程吗? [关闭]
【发布时间】:2011-01-08 11:04:15
【问题描述】:

我一直在考虑向我的应用程序添加线程过程以加快执行速度,但问题是我真的不知道如何使用线程,或者什么被认为是“线程安全的”。例如,游戏引擎如何在其渲染过程中使用线程,或者在什么情况下线程只会被视为障碍?有人可以指出一些资源来帮助我了解更多信息或在这里解释吗?

【问题讨论】:

  • 这是非常笼统的。线程只是执行命令的工作人员。 “线程安全”是确保两个或多个线程在交互时不会引起问题。就使用线程的游戏引擎而言……有大约一百万种方法可以做到这一点。
  • 直言不讳。忘记添加线程。这就像说你对急救有基本的了解,并想做脑部手术。回去学习基础知识。
  • 这个问题太宽泛了,无法以任何合理的方式回答。

标签: java c++ python perl multithreading


【解决方案1】:

这是一个非常广泛的话题。但如果我对线程一无所知,以下是我想知道的事情:

  • 它们是单个进程中“并行”发生的执行单元 - 这意味着处理器中的当前执行单元会快速切换。这可以通过不同的方式来实现。切换称为“上下文切换”,这会产生一些开销。

  • 他们可以共享内存!这是可能出现问题的地方。我将在后面的要点中更深入地讨论这一点。

  • 并行化应用程序的好处是使用机器不同部分的逻辑可以同时发生。也就是说,如果您的进程的一部分是 I/O 密集型的,而它的一部分是 CPU 密集型的,则 I/O 密集型操作不必等到 CPU 密集型操作完成。如果您有一个多核处理器,某些语言还允许您同时运行线程(因此也可以并行化 CPU 密集型操作),但情况并非总是如此。

  • 线程安全意味着没有竞态条件,这是一个术语,用于在您的进程执行取决于时间时发生的问题(您不想依靠)。例如,如果您有线程AB 都在递增共享计数器C,您可以看到A 读取C 的值,然后B 读取@987654327 的值的情况@,然后AC+1 覆盖C,然后BC+1 覆盖C。请注意,C 实际上只增加了一次!

  • 避免竞争条件的几种常见方法包括同步,它排除了对共享状态的相互访问,或者根本没有任何共享状态。但这只是冰山一角——线程安全是一个相当广泛的话题。

希望对您有所帮助!了解这是对需要大量学习的东西的快速介绍。我建议您找到有关多线程的资源,使用您喜欢的语言,不管是什么语言,并仔细阅读。

【讨论】:

  • 这对我帮助很大!谢谢!
  • +1 对该主题的良好介绍。
  • @Orm:非常欢迎;我很高兴它有帮助。
  • 这实际上让我了解了如何线程化我的渲染。将包含存储游戏对象的容器分成两半,然后让两个线程同时渲染前半部分或后半部分。或者将容器分成四等分或八等分。如果我在这方面错了,请立即阻止我。
  • @Orm:我不熟悉游戏开发,但我猜瓶颈是实际渲染到屏幕上?因此,如果您有多个线程通过游戏对象为图像创建屏幕外缓冲区,并且渲染器可以快速交换预先计算的缓冲区,那么这应该会加快速度。然后,您必须小心这些线程如何拆分要渲染的对象,您的拆分想法听起来很合理。
【解决方案2】:

关于线程,您应该了解四件事。

  1. 线程类似于进程,但它们共享内存。

  2. 线程通常具有硬件、操作系统和语言支持,这可能使它们比进程更好。

  3. 线程需要支持许多繁琐的小事情(如锁和信号量),因此它们不会将共享的内存置于不一致的状态。这使得它们有点难以使用。

  4. 锁定不是自动的(在我知道的语言中),因此您必须非常小心它们(隐式)共享的内存。

【讨论】:

    【解决方案3】:

    线程不会加速应用程序。算法加速应用程序。如果合适,可以在算法中使用线程。

    【讨论】:

    • 线程可以在某些条件下加速您的应用程序。例如串行时,阻塞任务可以拆分为并行任务。对多核系统的影响增加了,这正在成为常态。考虑一个必须发出 TCP/IP 请求并等待响应的任务。如果此任务在一个线程上阻塞,其中 10 个将花费 10 倍的时间。如果并行化,这可以减少到刚刚超过 1 倍的时间。
    • ...或者这只是对术语的更正? :)
    • 是的,我在算法课上学习过,并且一直在学习算法,但我想在多核处理器成为常态的情况下扩大我的视野。
    • 对于反对者:我坚信只有在有意义的情况下才将线程引入算法。不早了。
    【解决方案4】:

    好吧,也许有人会更好地回答这个问题,但线程的目的是进行不会冻结用户界面的后台处理。你不想停止接受键盘输入或鼠标输入,然后告诉用户,“等一下,我想完成这个计算,再过几秒钟就可以了。” (但令人惊讶的是,商业程序这样做了多少次。

    就线程安全而言,它意味着一个没有某些内部保存状态的函数。如果是这样,您就不能有多个线程同时使用它。

    就线程编程而言,你只需要开始做,然后你就会开始遇到线程编程特有的各种问题,例如同时访问数据,在这种情况下你必须决定使用一些同步方法,例如作为关键部分或互斥体或其他东西,每个部分的行为都有细微的差别。

    就进程和线程之间的区别(您没有问过)而言,进程是操作系统级别的实体,而线程与程序相关联。在某些情况下,您的程序可能想要创建进程而不是线程。

    【讨论】:

    • 尽管任何无状态的东西都是线程安全的,但线程安全并不意味着无状态
    • 抱歉,我的心情很挑剔......“......线程的目的是进行不会冻结用户界面的后台处理。” - 读起来好像这是线程的唯一目的,这绝对不是真的,尽管它是用途之一。
    【解决方案5】:

    线程只是一种同时执行多个事物的方式(假设它们正在运行的平台能够并行执行)。线程安全很简单(嗯,线程没有什么是真正简单的)确保线程不会以有害的方式相互影响。

    一般来说,您不太可能看到系统使用多个线程在屏幕上渲染图形,因为这可能会带来多重性能影响和复杂性问题。但是,与状态管理(或 AI)相关的其他任务可能会转移到单独的线程中。

    【讨论】:

      【解决方案6】:

      穿线的第一条规则:不要穿线。线程的第二条规则:如果你必须违反规则一……不要。第三条规则:好的,很好,你必须使用线程,所以在继续之前,请先了解陷阱,了解锁定和常见的线程问题,如死锁和活锁。

      了解线程不会加速任何事情,它只对后台长时间运行的进程有用,允许用户对应用程序执行其他操作。如果您必须允许用户与应用程序交互,而应用程序在后台执行其他操作,例如轮询套接字或等待来自应用程序其他地方的异步输入,那么您可能确实需要线程。

      Effective JavaClean Code 中的线程部分很好地介绍了线程及其陷阱。

      【讨论】:

      • 概括的第一条规则:不要概括。
      • 多线程确实在您有一个可并行的、受 CPU 限制的任务并且有多个处理器(或内核)可用时提供加速。将工作分成 n 个线程,并在大约 1/n 的时间内完成工作,其中 n 小于或等于处理器的数量。
      • 这是真的,而且现在比以往任何时候都更适用于更多的多核处理器。取点。但是,即使在多处理器环境中仅使用线程进行优化也是一个冒险的提议,仅当您的架构必要异步时才可取,例如在编写某种类型的服务器时会分拆多个工作人员等.
      • 关于“不要线程”我试图提出(并且可能是拙劣)的观点是线程会为您的代码库带来许多风险和不可预测性,如果可能的话,最好避免.仅仅为了“加速”应用程序而进行线程化并不是一个好主意,尤其是在锁、互斥锁等可以创建越来越复杂和不可预测的环境的 OO 环境中。是龙。
      • 好吧,因为我最初的渲染引擎设计被证明存在根本性的缺陷,所以在这次修改之后我就不需要线程了。
      【解决方案7】:

      由于问题被标记为“Java”,我假设您熟悉 Java,在这种情况下,这是一个很棒的介绍性教程 http://java.sun.com/docs/books/tutorial/essential/concurrency/

      【讨论】:

        【解决方案8】:

        Orm,很好的问题要问。我认为所有认真的程序员都应该了解线程,因为最终你至少考虑使用它们,并且你真的希望在它发生时做好准备。并发错误可能非常微妙,避免它们的最佳方法是了解哪些习惯用法是安全的(-ish)。

        我强烈建议您花时间阅读 Doug Lea 的Java 并发编程:设计原则和模式一书: http://gee.cs.oswego.edu/dl/cpj/

        Lea 不仅花时间教您概念,还向您展示使用并发编程原语的正确和错误方法(在 Java 中,但对于使用共享内存锁定/信号样式的任何其他环境也很有帮助并发)。最重要的是,他教导人们尊重并发编程的难度。

        我应该补充一点,这种并发编程风格是最常见但不是唯一的方法。还有消息传递,它更安全,但会迫使您以不同的方式构建算法。

        【讨论】:

          【解决方案9】:

          由于原帖非常宽泛,而且还用 C++ 标记,我认为以下几点是相关的:

          Boost 线程库的维护者 Anthony Williams 一直在写一本名为“C++ Concurrency in Action”的书,您可以在 here 找到它的描述。第一章(介绍性)以 pdf 格式免费提供 here

          此外,Herb Sutter(以他的“Exceptional C++”系列而闻名)一直在写一本名为“Effective Concurrency”的书,其中许多文章都以草稿形式提供here

          【讨论】:

            【解决方案10】:

            有一本好书,Java Concurrency in Practicehttp://www.javaconcurrencyinpractice.com/

            【讨论】:

            • 虽然这是一本很棒的书,但它假定您事先了解 Java 中的基本并发机制,而提问者可能还没有准备好。
            • 对了,我忘了里面没有介绍。
            猜你喜欢
            • 1970-01-01
            • 1970-01-01
            • 2014-03-11
            • 2020-08-16
            • 2011-05-08
            • 2021-02-13
            • 2014-03-16
            • 2012-04-09
            相关资源
            最近更新 更多