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


线程与进程


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


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

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

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

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

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

平行性


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


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


总结


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


目录
相关文章
|
2月前
|
缓存 负载均衡 安全
在Python中,如何使用多线程或多进程来提高程序的性能?
【2月更文挑战第17天】【2月更文挑战第50篇】在Python中,如何使用多线程或多进程来提高程序的性能?
|
3月前
|
人工智能 Java API
Python 潮流周刊#28:两种线程池、四种优化程序的方法
Python 潮流周刊#28:两种线程池、四种优化程序的方法
25 1
|
6月前
|
机器学习/深度学习 缓存 Java
Python 线程,进程,多线程,多进程以及并行执行for循环笔记
Python 线程,进程,多线程,多进程以及并行执行for循环笔记
441 0
Python 线程,进程,多线程,多进程以及并行执行for循环笔记
|
5月前
|
数据采集 人工智能 数据可视化
Scala多线程爬虫程序的数据可视化与分析实践
Scala多线程爬虫程序的数据可视化与分析实践
|
3天前
|
数据采集 缓存 前端开发
LabVIEW用了多线程,程序是不是会跑的更快些
LabVIEW用了多线程,程序是不是会跑的更快些
|
5天前
|
消息中间件 程序员 调度
Python并发编程:利用多线程提升程序性能
本文探讨了Python中的并发编程技术,重点介绍了如何利用多线程提升程序性能。通过分析多线程的原理和实现方式,以及线程间的通信和同步方法,读者可以了解如何在Python中编写高效的并发程序,提升程序的执行效率和响应速度。
|
2月前
|
缓存 编译器 程序员
C/C++编译器并行优化技术:并行优化针对多核处理器和多线程环境进行优化,以提高程序的并行度
C/C++编译器并行优化技术:并行优化针对多核处理器和多线程环境进行优化,以提高程序的并行度
89 0
|
2月前
|
Python
在Python中,如何使用多线程或多进程来实现任务的并行执行?
在Python中,如何使用多线程或多进程来实现任务的并行执行?
147 1
|
3月前
|
安全 Java 开发者
Python多线程编程实战:提高程序执行效率的策略
Python多线程编程实战:提高程序执行效率的策略
126 1