【问题标题】:I don't understand multi-threaded programming我不懂多线程编程
【发布时间】:2010-11-12 19:04:12
【问题描述】:

有人可以向我解释一下,当单核 cpu 一次只能做一件事时,多线程应用程序如何更快。如果我有 10 个线程,那么在任何给定时刻,只有 1 个线程在单个核心 cpu 上真正“运行”,所有额外的线程只会增加上下文切换开销。因此,如果每个线程有 10 条指令要处理,那么最后我仍然按顺序处理 100 条指令加上上下文切换开销。我在这里遗漏了什么吗?

【问题讨论】:

    标签: multithreading


    【解决方案1】:

    一个关于香蕉的有用类比

    想象一下有 4 条收银台的超市。但是只有一名收银员。她应该在单个寄存器上工作还是在所有 4 个寄存器上工作,在它们之间移动?

    显而易见的答案是,她应该留在一个收银台上,以免浪费时间在结账通道之间移动。

    但现在想象一下,当您购买水果时,秤可能需要长达 5 分钟的时间来重新校准每种特定类型的水果。

    当天平重新校准并且收银机被捆绑时,突然间,整体而言,旋转到下一个车道并在那儿敲响一些物品,而不是仅仅等待天平再次准备好。

    规模校准是非 CPU 工作(如磁盘 I/O、网络延迟等)。旋转到下一个寄存器就是切换到另一个线程。你有它。

    【讨论】:

    • 真棒类比! Stackoverflow 摇滚。
    • 我错过了这样一个事实,即 I/O 控制器可以独立于 CPU 做事,而现在事情变得更有意义了。
    • 这实际上是一个很好的类比。我必须记住这一点。
    • 很好的类比。我喜欢使用的是服务员服务表。服务员坐在那里看着一张桌子上的人吃东西以防万一他们需要什么,而其他等待服务的人都饿死了,这是没有意义的。当一张桌子进行一些阻塞操作时,比如决定点什么或争论支票,服务员可以为另一张桌子提供服务。
    【解决方案2】:

    是的,您忽略了进程可能会阻塞以等待 I/O 的事实。因此,如果您在应用程序中只使用 ONE THREAD,如果它阻塞等待 I/O 完成,将会非常缓慢。

    另一方面,如果您有多个线程,您的应用程序可能会有几个线程等待 I/O 完成,但其余线程“正在执行”,而操作系统允许它访问单个处理器。

    请记住,与 CPU 操作相比,I/O 操作要慢数量级

    并且是的。即使在单核中,多线程应用程序也可能比单线程应用程序更快。考虑像 APACHE 这样的服务器进程在单个线程上运行的情况。每次有一个连接等待 I/O 完成时,连接的其余部分将停止等待该 I/O 操作完成。当然还有 ASYNC-IO。但是,让像 Apache 这样的大型服务器使用 ASYNC-IO 在单线程上运行的编程模型太复杂,无法维护、改进或其他任何事情。

    【讨论】:

    • 此外,很多现代单核 CPU 都支持超线程,可以加快多线程应用程序的速度。
    • 好的,这解释了其中一些,但现在你说的是关于阻塞 I/O 的事情,这指出了我困惑的根源。那么你是说一旦 CPU 分派了一个 I/O 请求,它就不必等待该请求完成来执行与该请求无关的其他事情?
    • @davidk01:正确。如果 OS 内核调度一个 I/O 请求,将 立即 将处理器交给另一个 THREAD/PROCESS。在等待像 I/O 操作这样慢的东西时浪费 CPU 时间是没有意义的......
    • 这是最好的答案,但我认为您夸大了 MT 应用程序可能更快的可能性。它完全取决于工作负载。如果计算应用程序(例如财务数据的 Excel)笨拙地产生线程以并行化计算,它将在单核上运行得更慢。
    【解决方案3】:

    你说得对,单核处理器并没有更快。大多数程序一次做很多事情。大多数这些操作对于处理器来说都是“突发的”。他们做一些事情,等待输入或输出完成,然后再做一些。多线程编程允许另一个操作在等待期间使用处理器。请记住,所有处理器基本上都做同样的事情。不同之处在于他们执行操作的速度。目标是让处理器尽可能多地忙于做有用的事情。多线程编程只是一种让程序员更容易实现目标的方法。

    【讨论】:

    • 错了,如果线程大量处于等待状态(例如数据库客户端),单核性能会更快
    【解决方案4】:

    在单核上,当然不是更快。但它可以使系统更具响应性,在执行长时间运行的任务时不会显得死气沉沉。

    【讨论】:

    • 错了,如果线程大量处于等待状态(例如数据库客户端),单核性能会更快
    • 同意,但这更多的是编程模型问题而不是线程问题。您也可以使用单线程堆栈来管理等待状态。 (当然不是你想要的)。
    【解决方案5】:

    这真的取决于线程在做什么。如果存在相对较大的延迟,则另一个线程可以在其他线程等待“自己”的同时完成其工作。

    【讨论】:

      猜你喜欢
      • 2021-04-09
      • 2016-11-02
      • 2017-05-12
      • 1970-01-01
      • 2011-01-18
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多