发布于 2026-01-06 5 阅读
0

多线程和并行编程

多线程和并行编程

多线程是一种广泛应用的编程和执行模型,它允许在同一个进程中存在多个线程。这些线程可以并行运行,并且共享相似的地址空间。好的,让我们从头开始。

什么是线程?

执行单元thread是能够由调度器(通常是操作系统的一部分)独立管理的最小程序指令序列。大多数情况下,一个线程存在于一个进程中,而多个线程可以存在于同一个进程中,这就是多线程。

替代文字

我认为计算机科学家看待 A 的Thread方式,和化学家看待 An 的方式是一样的Atom

这些threads进程并发运行并共享资源。线程threads和进程的实现方式在不同的操作系统中有所不同,但在大多数情况下,线程都是进程的一个组成部分。

什么是流程?

进程是程序的实例,通常彼此独立运行。例如,如果您启动一个 Java 程序,操作系统会生成一个新的进程,process该进程与其他程序并行运行。在这些进程内部,我们可以使用线程并发执行代码,从而最大限度地利用 CPU 的可用核心。

替代文字

与线程不同,进程之间不共享资源。进程process是资源的单位,而线程是调度和执行的单位。

线程池

创建一个全新的操作系统线程需要分配内存和 CPU 指令来进行设置和销毁。为了更好地管理线程的使用,并避免创建新线程,操作系统或平台提供了一种Thread Pool特性,允许应用程序使用已存在的线程。

这是一种更高效的多线程处理方式,无需手动创建或销毁线程。此外,操作系统能够识别线程池中未被使用的线程,从而在线程迭代过程中自动“跳过”该线程。

线程的描述性编程表示

我们将通过 Java 中的两个类来了解线程的实现方式,Executors以及Runnable

  • Java 中的Executor Executors类抽象了大部分手动创建线程的过程。它们能够运行异步任务,并且通常管理一个线程池,因此我们无需手动创建新线程。

该类Executors提供了便捷的工厂方法,用于创建不同类型的执行器服务。在下面的示例中,我们使用了一个线程池大小为 1 的执行器。

替代文字

结果看起来与上面的示例类似,但运行代码时你会注意到一个重要的区别:Java 进程永远不会停止!Executors必须显式停止——否则它们会一直监听新任务。

ExecutorService为此,该服务提供了两种方法:shutdown()一种是等待当前正在运行的任务完成,另一种shutdownNow()是中断所有正在运行的任务并立即关闭执行器。此服务主要用于处理套接字连接,以方便异步调用(源-接收器连接)。

  • Runnable ARunnable是一个函数式接口,定义了一个无参的 void 方法run()。在启动新线程之前,必须指定该线程要执行的代码,通常称为任务,这可以通过实现一个 Runnable 接口来完成Runnable。请注意,您可以拥有任意数量的任务。

替代文字

以上例中使用了 Java 8 的 lambda 表达式,将当前线程的名称打印到控制台。首先,我们在启动新线程之前,直接在主线程上执行该可运行对象。请参见下面的示例输出。



Hello main
Hello Thread-0
Done!


Enter fullscreen mode Exit fullscreen mode

或者说:



Hello main
Done!
Hello Thread-0


Enter fullscreen mode Exit fullscreen mode

由于并发执行,我们无法预测可运行对象会在打印之前还是之后被调用,因此会出现两种可能的输出。Done执行顺序是不确定的,这使得并发编程在大型应用程序中成为一项复杂的任务。尽管线程也可以被置于睡眠状态一段时间。

多线程深度解析

正如我们之前明确指出的,一个multi-threaded程序包含两个或多个可以同时运行的部分,每个部分可以同时处理不同的任务,从而最大限度地利用可用资源,尤其是在您的计算机有多个 CPU 的情况下。

替代文字

Multi-threading它将多任务处理的概念扩展到应用程序中,允许将单个应用程序中的特定操作细分为单独的线程。它使你能够编写允许多个活动在同一程序中并发执行的代码。

少数编程语言支持多线程multi-threading,其中大多数是面向对象编程语言(OOP)。例如JavaJavaScript、CJavaScriptC++以及一些.NET框架。一些解释型语言也支持多线程,例如Ruby MRIJavaScriptRubyCPythonJavaScript Python。如果你期待看到 JavaScript 的多线程Javascript,那么恐怕要失望了,因为 JavaScript 不支持多线程,这是因为JavaScript浏览器中的解释器是单线程的。

高度多线程应用程序

几乎所有设计良好的应用程序都支持多线程。我们来看看浏览器。大多数浏览器都是多线程的,从firefoxWindows到SafariWindows Chrome,还有很多其他浏览器。但今天我们主要讨论的是Chrome……

Google
Chrome 采用多进程架构,每个进程都高度依赖多线程。其主要目标是保持主线程(浏览器进程中的“UI”线程)和 I/O 线程(每个进程用于处理进程间通信的线程)的响应速度。这意味着将任何阻塞式 I/O 或其他耗时操作卸载到其他线程。

替代文字

在Chrome 浏览器中Chrome,你打开的每个标签页都会拥有自己的内容进程。五个标签页,五个进程;一百个标签页,一百个进程。这种方式虽然能最大限度地提升性能,但会显著增加内存消耗和电池续航时间。你是否曾经好奇为什么任务管理器中 Chrome 的 CPU 使用率总是很高?原因就在这里。

每个 Chrome 进程都有,

  • main thread线程用于更新用户界面并运行 Blink 的大部分功能。
  • IO thread线程处理进程间通信 (IPC) 和网络请求
  • 还有一些special-purpose threads
  • 一池general-purpose threads

与 Firefox 相比,Chrome
Chrome为每个标签页创建一个内容进程,Firefox而 Firefox 默认最多会启动四个内容进程线程。在 Firefox 中,前四个标签页各自使用这四个进程,后续标签页则使用这些进程内的线程。同一个进程内的多个标签页共享内存中已有的浏览器引擎,而不是各自创建自己的引擎。

线程与进程

线程与传统的多任务处理方式在很多方面都不同:

  • 进程通常是独立的,而线程是进程的子集。
  • 进程携带的状态信息比线程多得多,而进程内的多个线程共享进程状态以及内存和其他资源。
  • 进程拥有独立的地址空间,而线程共享地址空间。
  • 进程之间仅通过系统提供的进程间通信机制进行交互。
  • 同一进程内线程间的上下文切换通常比进程间的上下文切换速度更快。

平行结构

并行性是指将工作分配到多个单元中,这样既不会影响最终产品的质量,又能最大限度地减少总执行时间。

并行执行是指两个(或多个)任务同时运行的能力。并发性代表可能性,而并行性则代表现实。

结论

多线程如今已成为现代软件开发的重要组成部分。它被众多编程语言和平台所支持,甚至延伸至操作系统层面。掌握多线程的使用方法无疑能够帮助开发者构建更优秀的应用程序。

文章来源:https://dev.to/kwereutosu/multi-threading-and-parallel-programming-1l9m