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

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

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

什么是线程(thread)?


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

image.png

当计算机科学家看到Thread(线程)时就像化学家看到Atom(原子)一样。


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


什么是进程(process)?


进程是通常彼此独立运行的程序的实例。例如,如果启动Java程序,则操作系统会产生一个新程序,该程序process(进程)可与其他程序并行运行。在这些进程中,我们可以利用线程并发执行代码,因此我们可以充分利用CPU的可用内核。

image.png

与线程不同,进程不会彼此共享资源。process(进程)是资源的单位,而thread(线程)是调度和执行的单位。


线程池


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


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


线程的描述性编程表示


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


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

该类Executors提供了方便的工厂方法来创建各种执行程序服务。在下面的示例中,我们使用大小为1的线程池的执行程序。


结果看起来类似于上面的示例,但是在运行代码时,您会注意到一个重要的区别,java进程永不停止!Executors必须明确停止-否则他们会继续听新任务。


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


可运行的 Runnable是定义单个空隙无参数方法功能接口run()。在开始新线程之前,您必须指定此线程要执行的代码,通常称为任务,这是通过实现来完成的Runnable。请注意,您可以拥有尽可能多的任务。

image.png


对于上面的示例,我们利用Java 8 lambda表达式将当前线程名称打印到控制台。首先,我们在开始新线程之前直接在主线程上执行runnable。请参见下面的示例输出。

Hello main
Hello Thread-0
Done!


或者这样:

Hello main
Done!
Hello Thread-0



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


深入多线程


就像我们前面已经明确指出的那样,一个multi-threaded(多线程)程序包含两个或多个可以同时运行的部分,并且每个部分可以同时处理不同的任务,特别是在计算机具有多个CPU时,可以最佳利用可用资源。


Multi-threading(多线程)将多任务处理的概念扩展到了应用程序中,您可以在其中将单个应用程序中的特定操作细分为各个线程。它使您可以编写一种方式,使多个活动可以在同一程序中同时进行。

image.png

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


大量的多线程应用程序


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


Google Chrome


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


image.png


在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个进程,其他标签则使用这些进程中的线程。一个进程中的多个选项卡共享内存中已经存在的浏览器引擎,而不是每个选项卡都创建自己的浏览器。


线程与进程


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


进程通常是独立的,而线程作为进程的子集存在。

进程比线程携带更多的状态信息,而一个进程中的多个线程共享进程状态以及内存和其他资源。

进程具有单独的地址空间,而线程共享它们的地址空间。

进程仅通过系统提供的进程间通信机制进行交互。

同一进程中线程之间的上下文切换通常比进程之间的上下文切换发生得更快。

平行性


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


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


总结


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


目录
相关文章
|
3天前
|
Java 开发者
如何通过易语言多线程提升程序响应速度
如何通过易语言多线程提升程序响应速度
97 62
|
16天前
|
并行计算 安全 Java
Python 多线程并行执行详解
Python 多线程并行执行详解
32 3
|
2天前
|
监控 Java API
|
2月前
|
算法 Java
JUC(1)线程和进程、并发和并行、线程的状态、lock锁、生产者和消费者问题
该博客文章综合介绍了Java并发编程的基础知识,包括线程与进程的区别、并发与并行的概念、线程的生命周期状态、`sleep`与`wait`方法的差异、`Lock`接口及其实现类与`synchronized`关键字的对比,以及生产者和消费者问题的解决方案和使用`Condition`对象替代`synchronized`关键字的方法。
JUC(1)线程和进程、并发和并行、线程的状态、lock锁、生产者和消费者问题
|
2月前
|
Rust 并行计算 安全
揭秘Rust并发奇技!线程与消息传递背后的秘密,让程序性能飙升的终极奥义!
【8月更文挑战第31天】Rust 以其安全性和高性能著称,其并发模型在现代软件开发中至关重要。通过 `std::thread` 模块,Rust 支持高效的线程管理和数据共享,同时确保内存和线程安全。本文探讨 Rust 的线程与消息传递机制,并通过示例代码展示其应用。例如,使用 `Mutex` 实现线程同步,通过通道(channel)实现线程间安全通信。Rust 的并发模型结合了线程和消息传递的优势,确保了高效且安全的并行执行,适用于高性能和高并发场景。
42 0
|
1月前
|
SQL 存储 监控
SQLServer事务复制延迟优化之并行(多线程)复制
【9月更文挑战第12天】在SQL Server中,事务复制延迟会影响数据同步性。并行复制可通过多线程处理优化这一问题,提高复制效率。主要优化方法包括:配置分发代理参数、优化网络带宽、调整系统资源、优化数据库设计及定期监控维护。合理实施这些措施可提升数据同步的及时性和可靠性。
|
2月前
|
开发框架 Android开发 iOS开发
跨平台开发的双重奏:Xamarin在不同规模项目中的实战表现与成功故事解析
【8月更文挑战第31天】在移动应用开发领域,选择合适的开发框架至关重要。Xamarin作为一款基于.NET的跨平台解决方案,凭借其独特的代码共享和快速迭代能力,赢得了广泛青睐。本文通过两个案例对比展示Xamarin的优势:一是初创公司利用Xamarin.Forms快速开发出适用于Android和iOS的应用;二是大型企业借助Xamarin实现高性能的原生应用体验及稳定的后端支持。无论是资源有限的小型企业还是需求复杂的大公司,Xamarin均能提供高效灵活的解决方案,彰显其在跨平台开发领域的强大实力。
36 0
|
2月前
|
Java 调度
|
2月前
|
安全 C# 开发者
【C# 多线程编程陷阱揭秘】:小心!那些让你的程序瞬间崩溃的多线程数据同步异常问题,看完这篇你就能轻松应对!
【8月更文挑战第18天】多线程编程对现代软件开发至关重要,特别是在追求高性能和响应性方面。然而,它也带来了数据同步异常等挑战。本文通过一个简单的计数器示例展示了当多个线程无序地访问共享资源时可能出现的问题,并介绍了如何使用 `lock` 语句来确保线程安全。此外,还提到了其他同步工具如 `Monitor` 和 `Semaphore`,帮助开发者实现更高效的数据同步策略,以达到既保证数据一致性又维持良好性能的目标。
40 0