用线程编程,有什么好处?

时间:2013-09-30 16:50:16

标签: multithreading performance

鉴于单核CPU,使用线程编码有什么好处?

至少在Java实现方面,考虑到单核心限制,自然地扩展到任何其他语言似乎很直观,您可能有多个线程执行各种操作,但这些过程是有时间限制和切换的。

给定流程A和流程B:

执行流程A的一半,完成流程B,然后完成流程A的后半部分VS执行流程A然后B?

似乎线程之间的切换会引入时间延迟,这会延长两个进程的总体完成时间VS不切换,只是完成A然后B。

5 个答案:

答案 0 :(得分:6)

在单核系统上使用线程的原因只是允许那些原本会使用所有CPU的进程被其他需要更快完成的任务抢占。使系统成为多线程的最常见原因是即使在执行长计算时也要有响应式用户界面。

当然,任何操作都可能需要很长时间(读取文件,访问数据库,调整照片大小,重新计算电子表格),并且这些操作可以在单独的线程上执行,以允许线程响应用户输入一直操作。

二十年前,例如,很少有多CPU系统或允许多线程的操作系统,因此几乎每个程序都是单线程的,并且创建了许多框架以允许系统具有UI和仍然做I / O.此标准机制是一个事件循环,其中所有事件(UI,网络,计时器等)都在一个大循环中处理。

这种类型的系统意味着在文件I / O和计算等过程中会保留UI。为了不过多地阻止UI,您必须以块的形式执行I / O(例如,一次读取4k文件),处理块之间的任何传入UI事件。这实际上只是一个让系统保持运行的黑客攻击,但很难让系统像这样顺利运行,因为你不知道处理事件的频率。

解决方案是使用单独的线程重新计算电子表格或编写文件。通过这种方式,操作系统可以为这些线程提供公平的时间片,同时仍然抢占它们以运行UI,从而使UI始终具有响应性。

答案 1 :(得分:4)

执行线程不一定做任何有用的事情。典型的例子是从磁盘读取 - 数据不会再存在几毫秒,在此期间处理器将处于未使用状态。线程允许程序的一个部分使用CPU,而程序的其他部分正在等待操作完成。

答案 2 :(得分:3)

原因很多。维基百科对其page about threads给出了一个不错的概述。

以下是一些OTOH:

  • I / O绑定任务受益于线程(尤其是网络应用程序)。
  • 即使在单核上,超线程处理器也可以加速多线程应用程序。
  • 可以指示线程等待(阻止)并唤醒特定事件,从而实现响应式事件驱动编程。

答案 3 :(得分:2)

如果您的程序必须“同时”执行多项操作,那么线程是一种很好的方法,特别是其中一些任务运行时间很长。否则,您会发现自己编写的代码看起来像程序中的操作系统调度程序,如果您下面的操作系统已经非常好用,那么这总是浪费时间。您会发现您的源代码主要是“调度程序”而不是“程序”,这非常不优雅。一个好的线程程序可以非常优雅和经济的源代码,这使自己看起来很好,节省时间。

有些运行时间得到/错了。在Ada的早期阶段,运行时环境将执行自己的线程调度,并且它从未非常令人满意。这部分是因为虽然Ada语言规范包含了线程的概念,但我们当时的操作系统往往没有提供它们。当编译器编写者开始使用底层操作系统线程时,Ada得到了更好的效果。

同样,Python并没有真正正确地使用底层操作系统线程;它使用Global Interpreter Lock破坏它。 Python通过改进多处理来回避整个问题(在Windows主机上不一定是件好事......)。

Windows的早期版本也没有执行线程,他们进行了协作式多任务处理。这取决于整个机器中的每个进程至少不时地调用任何OS例程。每个操作系统例程都会先咨询“调度程序”,看看是否有其他东西等待运行,然后再继续代表该程序应该做的事情。那时候有许多糟糕的节目不会打球并占据整个机器。当其他东西开始进行长度计算时,你无法继续玩纸牌游戏。

答案 4 :(得分:1)

你的课程的心理模型是什么?

如果它依赖于可能在不可预测的订单中发生的多个外部输入,并且如果您想要响应这些输入而做的事情并不简单且可能在时间上重叠......

那么为每个输入请求设置一个单独的线程是有意义的,并让该线程执行该请求所需的响应。

因此,例如,如果您的程序正在等待来自外部通道的输入请求,并且每个请求必须触发其自己的传出和传入消息协议,则可以非常简化代码以创建新线程(或 - 为每个请求使用旧的。

不知何故,人们似乎进入了劳动力队伍,认为线程只是为了提高速度(通过并行性)。 这是一个用途,只要它允许多个CPU芯片来启动, 但这绝不是唯一的用途。