Multithreading 使用线程编程有什么好处?

Multithreading 使用线程编程有什么好处?,multithreading,performance,Multithreading,Performance,给定一个单核CPU,使用线程编码有什么好处 至少在Java实现中,考虑到单核限制,自然地扩展到任何其他语言似乎是很直观的,您可能有多个线程执行各种操作,但进程是有时间限制和切换的 给定过程A和过程B: 执行流程A的一半,完成流程B,然后完成流程A的后半部分与执行流程A然后执行流程B有什么好处 线程之间的切换似乎会引入时间延迟,这将延长两个进程的总体完成时间,而不是不切换,只完成A然后B。执行线程不一定做任何有用的事情。典型的例子是从磁盘读取数据——在接下来的几毫秒内,数据将不在那里,在此期间,处

给定一个单核CPU,使用线程编码有什么好处

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

给定过程A和过程B:

执行流程A的一半,完成流程B,然后完成流程A的后半部分与执行流程A然后执行流程B有什么好处


线程之间的切换似乎会引入时间延迟,这将延长两个进程的总体完成时间,而不是不切换,只完成A然后B。执行线程不一定做任何有用的事情。典型的例子是从磁盘读取数据——在接下来的几毫秒内,数据将不在那里,在此期间,处理器将处于未使用状态。线程允许程序的一部分使用CPU,而程序的其他部分则在等待操作完成。

在单核系统上使用线程的原因仅仅是为了让原本会使用所有CPU的进程被其他需要更快完成的任务抢占。使系统多线程化的最常见原因是,即使在执行长时间计算时,也要有一个响应迅速的用户界面

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

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

这种类型的系统意味着UI在文件I/O和计算等过程中被挂起。为了不占用UI太多时间,您必须分块执行I/O(比如,一次读取4k文件),处理块之间传入的任何UI事件。这实际上只是一种让系统运行的技巧,但很难让系统像这样平稳运行,因为您不知道需要多久处理一次事件


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

原因有很多。Wikipedia提供了一个关于其

这里有几个例子:

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

如果您的程序必须“同时”执行多项任务,那么线程是一个不错的选择,特别是其中一些任务运行时间很长。否则,您会发现自己编写的代码看起来像程序中的操作系统调度器,如果您下面的操作系统已经有了一个非常好的代码,那么这总是浪费时间。你会发现你的源代码大部分是“调度器”,而不是太多的“程序”,这是非常不雅观的。一个好的线程程序可以在源代码中非常优雅和经济,这会使自己看起来很好并节省时间

有些运行时出错了。在Ada的早期,运行时环境将自己进行线程调度,这从来都不是很令人满意。这在一定程度上是因为,虽然Ada语言规范包含了线程的概念,但我们当时的操作系统通常不提供线程。当编译器编写者开始使用底层操作系统线程时,Ada变得更好了

类似地,Python并没有真正正确地使用底层OS线程;它用全局解释器锁破坏了它。Python通过使用多处理来回避整个问题(在Windows主机上不一定是件好事…)


早期版本的Windows也不执行线程,而是执行协作多任务。这取决于整个机器中的每个进程至少偶尔调用任何操作系统例程。每个操作系统例程都会先咨询“调度程序”,看看是否还有其他程序在等待运行,然后再继续执行它应该代表程序执行的操作。当时有很多糟糕的程序无法发挥作用,占据了整个机器。当其他人开始计算长度时,你无法继续玩纸牌游戏。

你的程序的心智模型是什么

如果它依赖于可能以不可预测的顺序发生的多个外部输入,并且如果您想要对这些输入做出响应的操作并不简单,并且可能在时间上重叠

然后,为每个输入请求指定一个单独的线程,并让该线程执行该请求所需的响应是有意义的

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

不知何故,人们似乎认为线程只是为了速度(通过并行性)而存在。 这是一个用途,只要它允许多个CPU芯片启动,
但这绝不是唯一的用途。

理由很多。I/O绑定任务受益于线程(尤其是网络应用程序