多线程(Multi-threading)和并行程序(Parallel Programming)详解

举报
海拥 发表于 2022/01/07 14:00:01 2022/01/07
【摘要】 🌊 作者主页:海拥🌊 简介:🏆CSDN全栈领域优质创作者、🥇HDZ核心组成员、🥈蝉联C站周榜前十🌊 粉丝福利:粉丝群 每周送6~9本书,不定期送各种小礼品,往期获奖公布多线程是一种广泛的编程和执行模型,该模型允许在一个进程的上下文中存在多个线程。这些线程中的每一个都可以并行运行,并且这些线程共享相似的地址空间。那么,让我们从头开始说。 什么是线程(thread)?thread的执...

🌊 作者主页:海拥
🌊 简介:🏆CSDN全栈领域优质创作者、🥇HDZ核心组成员、🥈蝉联C站周榜前十
🌊 粉丝福利:粉丝群 每周送6~9本书,不定期送各种小礼品,往期获奖公布

多线程是一种广泛的编程和执行模型,该模型允许在一个进程的上下文中存在多个线程。这些线程中的每一个都可以并行运行,并且这些线程共享相似的地址空间。那么,让我们从头开始说。

什么是线程(thread)?

thread的执行是可以由调度程序独立管理的最小程序指令序列,调度程序通常是操作系统的一部分。大多数情况下,一个线程存在于进程中,而多个线程可以存在于单个进程中,因此是多线程的。
在这里插入图片描述
当计算机科学家看到Thread(线程)时就像化学家看到Atom(原子)一样。

这些threads同时运行,并且共享资源。threads在操作系统的实现和进程在操作系统之间有所不同,但是在大多数情况下,线程是进程的组成部分。

什么是进程(process)?

进程是通常彼此独立运行的程序的实例。例如,如果启动Java程序,则操作系统会产生一个新程序,该程序process(进程)可与其他程序并行运行。在这些进程中,我们可以利用线程并发执行代码,因此我们可以充分利用CPU的可用内核。
在这里插入图片描述
与线程不同,进程不会彼此共享资源。process(进程)是资源的单位,而thread(线程)是调度和执行的单位。

线程池

创建一个全新的OS线程需要内存分配和CPU指令,以便对其进行设置和销毁。为了更好地处理线程的使用并避免创建新线程,操作系统或平台考虑了一项Thread Pool(线程池)功能,该功能使应用程序可以使用已经存在的线程。

这是处理多个线程而不处理其创建或销毁的更有效的方法。此外,操作系统知道何时未积极使用线程池中的线程,因此它们可以在线程迭代期间自动“跳过”它。

线程的描述性编程表示

我们将研究从JavaExecutors和Java中的两个类实现的线程Runnable

  • 执行程序Executors是Java中的一类,抽象了大多数手动线程创建过程。它们能够运行异步任务,通常可以管理线程池,因此我们不必手动创建新线程。

该类Executors提供了方便的工厂方法来创建各种执行程序服务。在下面的示例中,我们使用大小为1的线程池的执行程序。
在这里插入图片描述
结果看起来类似于上面的示例,但是在运行代码时,您会注意到一个重要的区别,java进程永不停止!Executors必须明确停止-否则他们会继续听新任务。

ExecutorService提供了两种方法用于此目的:shutdown()等待当前正在运行的任务完成,同时shutdownNow()中断所有正在运行的任务,并立即关闭执行程序。此服务通常在使用套接字连接时使用,以促进异步调用(Sink-Source连接)。

  • 可运行的 Runnable是定义单个空隙无参数方法功能接口run()。在开始新线程之前,您必须指定此线程要执行的代码,通常称为任务,这是通过实现来完成的Runnable。请注意,您可以拥有尽可能多的任务。
    在这里插入图片描述
    对于上面的示例,我们利用Java 8 lambda表达式将当前线程名称打印到控制台。首先,我们在开始新线程之前直接在主线程上执行runnable。请参见下面的示例输出。
Hello main
Hello Thread-0
Done!

或者这样:

Hello main
Done!
Hello Thread-0

我们有两个可能的输出,因为由于并发执行,我们无法预测在打印之前还是之后将调用runnable。该顺序是不确定的,因此使得并发编程在大型应用程序中成为一项复杂的任务。尽管线程也可以处于一定的睡眠时间。

深入多线程

就像我们前面已经明确指出的那样,一个multi-threaded(多线程)程序包含两个或多个可以同时运行的部分,并且每个部分可以同时处理不同的任务,特别是在计算机具有多个CPU时,可以最佳利用可用资源。
在这里插入图片描述
Multi-threading(多线程)将多任务处理的概念扩展到了应用程序中,您可以在其中将单个应用程序中的特定操作细分为各个线程。它使您可以编写一种方式,使多个活动可以在同一程序中同时进行。

有几种编程语言可以为腾出空间multi-threading,并且大多数语言是面向对象的编程语言(OOP)。语言,如JavaCC++甚至.NET框架。其他一些解释型语言也有所作为,例如Ruby MRIforRubyCPythonfor Python。如果您等着看Javascript,那么您将不是因为JavaScript不支持多线程,而是因为JavaScript浏览器中的解释器是一个单线程。

大量的多线程应用程序

几乎所有构建良好的应用程序都支持多线程。让我们看一下浏览器。大多数浏览器都是多线程的,从firefoxSafariChrome还有许多其他。但是今天我们要详细讨论Chrome

Google Chrome

Chrome具有多进程架构,并且每个进程都是高度多线程的。主要目标是使主线程(浏览器进程中的“ UI”线程)和IO线程(用于处理IPC的每个进程的线程)保持响应。这意味着将任何阻塞的I / O或其他昂贵的操作卸载到其他线程。

在这里插入图片描述

Chrome中,您打开的每个选项卡都有其自己的内容处理。五个标签,5个进程,一百个标签,100个进程。这种方法可最大程度地提高性能,但您会在内存消耗和电池寿命方面付出沉重的代价。有没有想过为什么任务管理器上的Chrome的CPU消耗总是很高?好吧,你去。

每个 chrome 进程都有

  • main thread 此线程更新UI并运行大多数Blink。
  • IO thread 此线程句柄的IPC和网络请求
  • 还有一些special-purpose threads
  • 一池的general-purpose threads

Chrome与Firefox的比较

虽然Chrome会为每个选项卡创建一个内容处理Firefox,但默认情况下最多旋转四个内容处理线程。在Firefox中,前4个标签分别使用这4个进程,其他标签则使用这些进程中的线程。一个进程中的多个选项卡共享内存中已经存在的浏览器引擎,而不是每个选项卡都创建自己的浏览器。

线程与进程

线程在许多方面与传统的多任务处理过程不同:

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

平行性

并行性与工作分散在多个单元中的概念有关,以这种方式不会损害最终产品,但会减少总执行时间。

并行执行是两个(或多个)任务同时运行的能力。虽然并发代表了可能性,但并行是现实。

总结

现在,多线程已成为现代软件开发的重要组成部分。它受到许多编程语言和平台的支持,并一直延伸到操作系统。知道如何使用多个线程可以肯定会导致开发人员构建更好的应用程序。

【版权声明】本文为华为云社区用户原创内容,转载时必须标注文章的来源(华为云社区)、文章链接、文章作者等基本信息, 否则作者和本社区有权追究责任。如果您发现本社区中有涉嫌抄袭的内容,欢迎发送邮件进行举报,并提供相关证据,一经查实,本社区将立刻删除涉嫌侵权内容,举报邮箱: cloudbbs@huaweicloud.com
  • 点赞
  • 收藏
  • 关注作者

评论(0

0/1000
抱歉,系统识别当前为高风险访问,暂不支持该操作

全部回复

上滑加载中

设置昵称

在此一键设置昵称,即可参与社区互动!

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。