首页
学习
活动
专区
工具
TVP
发布
精选内容/技术社群/优惠产品,尽在小程序
立即前往

多线程和并发有什么区别?

由于程序代码中存在的数据及控制依赖关系,单线程中所能发掘的指令并行潜力是有限的。为了发掘有限的指令级并行潜力而一味强化乱序执行和分支预测,以至于处理器复杂度和功耗急剧上升,有时候是得不偿失的。因此,现代微处理器多采用硬件多线程技术来发掘线程之间的线程级并行潜力。这样子允许在接口转换的专业领域之运算能力大幅提升:既使这样做对于提升单一程序或是线程的性能相当困难,但是目前多数的系统都是使用多任务的方式作业。能够明显的提升整体系统运算能力,总体吞吐量获得提升。有两种提升运算能力的主要技术分别是多进程与多线程。不过有些对多线程的批评如下:当共享硬件资源(像是缓存或是TLB)时多线程会造成干预。单线程的执行时间可能不会因为多线程而变短。硬件侦测技术有可能改变这一状况。多线程的硬件支持会牵涉到软件支持,如此程序与操作系统就需要比多过程化更大幅度的修改。

什么是多线程,它是如何在编程语言中实现的?

多线程是计算机科学中的一种技术,它允许多个线程在单个进程中同时运行。线程是一个轻量级的、独立的执行单元,可以与其他线程并行运行。每个线程都有自己的堆栈、程序计数器和局部变量。在编程语言中,多线程通常使用一个库或框架来实现,该库或框架提供一组用于创建、管理和同步线程的类和函数。

在 C++thread中,C++11 中的库提供了用于创建、管理和同步线程的类和函数。std::lock_guard和类用于创建代码的std::unique_lock关键部分,一次只能由一个线程访问。

在 C# 中,命名空间提供、 和System.Threading等类Thread,用于创建和管理线程。该关键字用于创建一次只能由一个线程访问的代码的关键部分。ThreadPoolMonitorlock

在 Python 中,该threading模块提供了Thread、Lock和 等Semaphore用于创建和管理线程的类。该类的acquire()和release()方法Lock用于创建一次只能由一个线程访问的关键代码段。

多线程是一种强大的技术,它允许多个线程在单个进程中并发运行,从而提高应用程序的性能和响应能力。大多数编程语言都提供用于创建和管理线程的库或框架,以及用于同步访问共享资源的机制。

多线程和多任务有什么区别?

多任务处理是现代操作系统中多个任务共享公共处理资源(CPU 和内存)时使用的术语。在任何时间点,CPU 只执行一个任务,而其他任务等待轮到它们执行。当 CPU 被重新分配给另一个任务(上下文切换)时,并行的错觉就实现了。多任务处理和多道程序设计之间存在一些主要差异(基于本文提供的定义)。多任务操作系统中的任务不是完整的应用程序(回想一下现代操作系统中的程序被划分为逻辑页)。任务也可以指一个进程被分割成子任务时执行的一个线程(后面会讲到多线程)。该任务不会劫持 CPU,直到它像在旧的多道程序模型中一样完成,而是拥有相当数量的 CPU 时间,称为量子(将在本文后面讨论时间共享)。为了便于记忆,多任务和多程序指的是一个类似的概念(共享 CPU 时间),一个用于现代操作系统,另一个用于旧操作系统。

由于线程是CPU利用率的基本单位。多线程不同于多任务允许同时执行多个任务,而多线程允许CPU同时处理单个任务的多个线程。多线程是基于线程的多任务处理。它允许同一进程的多个线程同时执行。一个例子是 Web 服务器,其中对所有传入请求的响应需要很多相同的程序逻辑和状态,但在一些事情上有不同的处理(网络套接字和调用者的 ID)等。另一个是 VLC 媒体播放器,其中一个线程用于打开 VLC 媒体播放器,一个用于播放特定歌曲,另一个线程用于将新歌曲添加到播放列表。多线程提高了响应能力。一个程序包含多个线程。因此,如果一个线程执行时间太长或被阻塞,线程的其余部分继续执行,没有任何问题。多线程成本更低。创建一个新进程并分配资源是一项耗时的任务,但在一个进程中分配多个线程并在它们之间切换相对容易。

对于单个进程,哪个是更好的选择:多线程还是多处理?

多线程在某些语言(Java、C#)中运行得更快,但在其他语言(Python、Ruby 等)中则不然。多线程消耗的内存也更少,因为线程可以共享内存。然而,编写多线程代码需要更加谨慎,因为一个线程的崩溃可能会导致整个程序崩溃,并且您需要更复杂的控制(例如互斥锁、信号量和其他我完全不明白它们最初含义的花哨词)充分发挥多核 CPU 的性能,而不会把事情搞砸。而当涉及到垃圾收集时,一次 GC 就可以停止整个程序。

另一方面,多进程易于编写和理解,因为每个进程都是独立的。一个进程中的崩溃不会影响其他进程。每个进程都分配自己的内存,因此总内存消耗很高(一种解决方法可能是 CoW),但由于每个进程都执行自己的 GC,因此没有停止世界的效果。引入全局状态需要数据库或 Redis 之类的东西,因此它会使您的体系结构更加复杂。多进程对横向扩展非常友好,因为每个进程都是一个整体的计算单元,进程运行在单台主机上还是多台主机上都没有区别。

哪一个更好?这实际上取决于您的用例。

多线程和并发有什么区别?

多线程是实现某些并发的工具;你使用多个线程来执行你的任务,在许多语言中,例如在 Java 或 C 中,你必须编写你的任务应该如何在你自己的不同线程之间拆分和组合的代码。并发是更广泛的目标,多线程可能会寻求实现这一目标。作为一个有点变态的反例,您可以通过生成多个 node.js 进程来实现并发响应对服务器的 http 请求。你将拥有并发性,但你不是(直接)依赖多线程来完成它,即使每个 node.js 处理多线程而不管这种特殊设置。

作为另一个例子,netty 和 node.js 利用并发事件范式,因此您可以使用单个进程来处理比依赖多线程并发服务的经典 http 服务器高几个数量级的请求负载。在其他实现中,例如在所谓的 Actor 模型下:每个 actor 可能是也可能不是不同的线程甚至进程,但是 actor 模型抽象抽象了您的任何多线程,并且您为 actor 编写代码,不知道如何actor 系统多线程(直到您需要对线程使用参数等进行性能调整)。因此,多线程是在单机上实现并发的核心工具,但并发是一个更广泛的目标和概念,可以通过其他工具来实现。

尽管如此,多线程是您使用的许多软件和操作系统的主要组成部分,只是对于高并发而言,它本身并不总是足够好,需要使用额外的处理器和架构模式来完成某些类型的工作负载的极端并发性。

  • 发表于:
  • 原文链接https://kuaibao.qq.com/s/20230206A02OZL00?refer=cp_1026
  • 腾讯「腾讯云开发者社区」是腾讯内容开放平台帐号(企鹅号)传播渠道之一,根据《腾讯内容开放平台服务协议》转载发布内容。
  • 如有侵权,请联系 cloudcommunity@tencent.com 删除。

扫码

添加站长 进交流群

领取专属 10元无门槛券

私享最新 技术干货

扫码加入开发者社群
领券