彻底理解 进程、线程、多进程、多线程

简介: 面试经常被问到的问题,今天给大家总结一下📌

进程和线程


进程

教科书上解释:进程是资源分配的最小单位

👀可以理解为:先加载程序A的上下文,然后开始执行A,保存程序A的上下文,调入下一个要执行的程序B的程序上下文,然后开始执行B,保存程序B的上下文。进程的生命周期有调入,执行,保存的过程。


线程

教科书上解释:线程是CPU调度的最小单位

👀可以理解为:一个应用程序的执行可能有多个分支和多个程序段,就好比要实现程序A,实际分成 a,b,c等多个块;这里的a,b,c就是线程,也就是说线程是共享了进程的上下文环境,单核任务中划分更为细小的CPU时间段。


进程和线程的区别

进程🌴: 每个进程都有自己独立的内存空间,不同进程之间的内存空间不共享。进程之间的通信有操作系统传递,导致通讯效率低,切换开销大。

线程🌴: 一个进程可以有多个线程,所有线程共享进程的内存空间,通讯效率高,切换开销小。(PS:共享意味着竞争,导致数据不安全,为了保护内存空间的数据安全,引入"互斥锁"。一个线程在访问内存空间的时候,其他线程不允许访问,必须等待之前的线程访问结束,才能使用这个内存空间)


多进程和多线程

共同点:

👉🏻表示可以同时执行多个任务,进程和线程的调度是由操作系统自动完成。

区别:

对比维度 多进程 多线程
数据共享、同步 数据共享复杂,需要用IPC;数据是分开的,同步简单 因为共享进程数据,数据共享简单,但也是因为这个原因导致同步复杂
内存、CPU 占用内存多,切换复杂,CPU利用率低 占用内存少,切换简单,CPU利用率高
创建销毁、切换 创建销毁、切换复杂,速度慢 创建销毁、切换简单,速度很快
编程、调试 编程简单,调试简单 编程复杂,调试复杂
可靠性 进程间不会互相影响 一个线程挂掉将导致整个进程挂掉


通信方式


进程间的通信方式

  1. 消息队列📍: 消息队列是消息的链表,具有特定的格式,存放在内存中并由消息队列标识符标识。消息队列存放在内核中,只有在内核重启(即,操作系统重启)或者显示地删除一个消息队列时,该消息队列才会被真正的删除。
  2. 套接字📍: 此方法主要用于在客户端和服务器之间通过网络进行通信。套接字是支持 TCP/IP 的网络通信的基本操作单元,可以看做是不同主机之间的进程进行双向通信的端点,简单的说就是通信的两方的一种约定,用套接字中的相关函数来完成通信过程。
  3. 信号量📍: 信号量是一个计数器,用于多进程对共享数据的访问,信号量的意图在于进程间同步。这种通信方式主要用于解决与同步相关的问题并避免竞争条件。
  4. 共享内存📍: 使得多个进程可以访问同一块内存空间,不同进程可以及时看到对方进程中对共享内存中数据的更新。这种方式需要依靠某种同步操作,如互斥锁和信号量等。可以说这是最有用的进程间通信方式。


线程间的通信方式(Java)

  1. volatile:保证了线程之间的可见性和有序性,禁止指令重排序,其中可见性就是可以让线程之间进行通信。
  2. 等待/通知机制:wait(),notify()和notifyAll()
  3. threadLocal 参见我的文章:《彻底明白ThreadLocal》


应用场景

多进程应用场景

  • nginx主流的工作模式是多进程模式(也支持多线程模型)
  • 几乎所有的web server服务器服务都有多进程的,至少有一个守护进程配合一个worker进程,例如apached,httpd等等以d结尾的进程包括init.d本身就是0级总进程,所有你认知的进程都是它的子进程;
  • chrome浏览器也是多进程方式。 (原因: ①可能存在一些网页不符合编程规范,容易崩溃,采用多进程一个网页崩溃不会影响其他网页;而采用多线程会。②网页之间互相隔离,保证安全,不必担心某个网页中的恶意代码会取得存放在其他网页中的敏感信息。)
  • redis也可以归类到“多进程单线程”模型(平时工作是单个进程,涉及到耗时操作如持久化或aof重写时会用到多个进程)


多线程应用场景

  • 线程间有数据共享,并且数据是需要修改的(不同任务间需要大量共享数据或频繁通信时)。
  • 提供非均质的服务(有优先级任务处理)事件响应有优先级。
  • 单任务并行计算,在非CPU Bound的场景下提高响应速度,降低时延。
  • 与人有IO交互的应用,良好的用户体验(键盘鼠标的输入,立刻响应)
  • 案例:

桌面软件,响应用户输入的是一个线程,后台程序处理是另外的线程;

如何选?

  1. 需要频繁创建销毁的优先用线程(进程的创建和销毁开销过大)
    这种原则最常见的应用就是Web服务器了,来一个连接建立一个线程,断了就销毁线程,要是用进程,创建和销毁的代价是很难承受的。
  2. 需要进行大量计算的优先使用线程(CPU频繁切换)
    所谓大量计算,当然就是要耗费很多CPU,切换频繁了,这种情况下线程是最合适的。
  3. 都满足需求的情况下,用你最熟悉、最拿手的方式
    至于“数据共享、同步”、“ 编程 、调试”、“可靠性”这几个维度的所谓的“复杂、简单”应该怎么取舍,只能说:没有明确的选择方法。选择原则:如果多进程和多线程都能够满足要求,那么选择你最熟悉、最拿手的那个。

🙇实际应用中基本上都是“进程+线程”的结合方式,千万不要真的陷入一种非此即彼的误区。



拓展知识

进程间的调度算法

  1. 先到先服务 从就绪队列中选择一个最先进入该队列的进程为之分配资源,使它立即执行并一直执行到完成或发生某事件而被阻塞放弃占用 CPU 时再重新调度。
  2. 短作业优先 从就绪队列中选出一个估计运行时间最短的进程为之分配资源,使它立即执行并一直执行到完成或发生某事件而被阻塞放弃占用 CPU 时再重新调度。
  3. 时间片轮转 时间片轮转调度是一种最古老,最简单,最公平且使用最广的算法,又称 RR(Round robin)调度。每个进程被分配一个时间段,称作它的时间片,即该进程允许运行的时间。
  4. 优先级调度 为每个流程分配优先级,首先执行具有最高优先级的进程,依此类推。具有相同优先级的进程以 FCFS 方式执行。可以根据内存要求,时间要求或任何其他资源要求来确定优先级。
  5. 多级反馈队列 前面介绍的几种进程调度的算法都有一定的局限性。如短进程优先的调度算法,仅照顾了短进程而忽略了长进程 。多级反馈队列调度算法既能使高优先级的作业得到响应又能使短作业(进程)迅速完成。,因而它是目前被公认的一种较好的进程调度算法,UNIX 操作系统采取的便是这种调度算法。


总结

比喻⭐:如果说进程是工厂,那么线程就是工厂里的工人,而工人是要干活的。工厂(进程)给工人(线程)提供了内存空间,让工人(线程)干活。

进程是资源分配的基本单位,而线程是CPU调度的基本单位。因此,某种意义上可以说在支持线程的操作系统中没有真正意义上的进程调度,而都是线程调度。线程的出现主要是为了弥补进程各种操作开销大的问题,除这点外,线程和进程是差不多的。多线程和多进程一样,一方面为了充分利用CPU资源,另一方面是为了优化用户交互体验。

🚀🚀🚀

目录
相关文章
|
5月前
|
安全 算法 Java
Java 多线程:线程安全与同步控制的深度解析
本文介绍了 Java 多线程开发的关键技术,涵盖线程的创建与启动、线程安全问题及其解决方案,包括 synchronized 关键字、原子类和线程间通信机制。通过示例代码讲解了多线程编程中的常见问题与优化方法,帮助开发者提升程序性能与稳定性。
230 0
|
2月前
|
Java 测试技术 API
【JUC】(1)带你重新认识进程与线程!!让你深层次了解线程运行的睡眠与打断!!
JUC是什么?你可以说它就是研究Java方面的并发过程。本篇是JUC专栏的第一章!带你了解并行与并发、线程与程序、线程的启动与休眠、打断和等待!全是干货!快快快!
522 2
|
2月前
|
JSON 网络协议 安全
【Java】(10)进程与线程的关系、Tread类;讲解基本线程安全、网络编程内容;JSON序列化与反序列化
几乎所有的操作系统都支持进程的概念,进程是处于运行过程中的程序,并且具有一定的独立功能,进程是系统进行资源分配和调度的一个独立单位一般而言,进程包含如下三个特征。独立性动态性并发性。
193 1
|
2月前
|
JSON 网络协议 安全
【Java基础】(1)进程与线程的关系、Tread类;讲解基本线程安全、网络编程内容;JSON序列化与反序列化
几乎所有的操作系统都支持进程的概念,进程是处于运行过程中的程序,并且具有一定的独立功能,进程是系统进行资源分配和调度的一个独立单位一般而言,进程包含如下三个特征。独立性动态性并发性。
215 1
|
10月前
|
存储 Linux API
【Linux进程概念】—— 操作系统中的“生命体”,计算机里的“多线程”
在计算机系统的底层架构中,操作系统肩负着资源管理与任务调度的重任。当我们启动各类应用程序时,其背后复杂的运作机制便悄然展开。程序,作为静态的指令集合,如何在系统中实现动态执行?本文带你一探究竟!
【Linux进程概念】—— 操作系统中的“生命体”,计算机里的“多线程”
|
5月前
|
数据采集 监控 调度
干货分享“用 多线程 爬取数据”:单线程 + 协程的效率反超 3 倍,这才是 Python 异步的正确打开方式
在 Python 爬虫中,多线程因 GIL 和切换开销效率低下,而协程通过用户态调度实现高并发,大幅提升爬取效率。本文详解协程原理、实战对比多线程性能,并提供最佳实践,助你掌握异步爬虫核心技术。
|
8月前
|
并行计算 Linux
Linux内核中的线程和进程实现详解
了解进程和线程如何工作,可以帮助我们更好地编写程序,充分利用多核CPU,实现并行计算,提高系统的响应速度和计算效能。记住,适当平衡进程和线程的使用,既要拥有独立空间的'兄弟',也需要在'家庭'中分享和并行的成员。对于这个世界,现在,你应该有一个全新的认识。
305 67
|
6月前
|
Java 数据挖掘 调度
Java 多线程创建零基础入门新手指南:从零开始全面学习多线程创建方法
本文从零基础角度出发,深入浅出地讲解Java多线程的创建方式。内容涵盖继承`Thread`类、实现`Runnable`接口、使用`Callable`和`Future`接口以及线程池的创建与管理等核心知识点。通过代码示例与应用场景分析,帮助读者理解每种方式的特点及适用场景,理论结合实践,轻松掌握Java多线程编程 essentials。
411 5
|
6月前
|
调度 开发工具 Android开发
【HarmonyOS Next】鸿蒙应用进程和线程详解
进程的定义: 进程是系统进行资源分配的基本单位,是操作系统结构的基础。 在鸿蒙系统中,一个应用下会有三类进程:
233 0
|
9月前
|
SQL 监控 网络协议
YashanDB进程线程体系
YashanDB进程线程体系