当前位置: 首页 > news >正文

面试必问:进程和线程的区别(从操作系统层次理解)

1.什么是进程?为什么要有进程?

进程有一个相当精简的解释:进程是对操作系统上正在运行程序的一个抽象。

这个概念确实挺抽象,仔细想想却也挺精准。

我们平常使用计算机,都会在同一时间做许多事,比如边看电影,边微信聊天,顺便打开浏览器百度搜索一下,我们所做的这么多事情背后都是一个个正在运行中的软件程序;这些软件想要运行起来,首先在磁盘上需要有各自的程序代码,然后将代码加载到内存中,CPU会去执行这些代码,运行中会产生很多数据需要存放,也可能需要和网卡、显卡、键盘等外部设备交互,这背后其实就涉及到程序对计算机资源的使用,存在这么多程序,我们当然需要想办法管理程序资源的使用。并且CPU如果只有一个,那么还需要操作系统调度CPU分配给各个程序使用,让用户感觉这些程序在同时运行,不影响用户体验。

理所当然,操作系统会把每个运行中的程序封装成独立的实体,分配各自所需要的资源,再根据调度算法切换执行。这个抽象程序实体就是进程。

所以很多对进程的官方解释中都会提到:进程是操作系统进行资源分配和调度的一个基本单位。

2.什么是线程?为什么要有线程?

在早期的操作系统中并没有线程的概念,进程是拥有资源和独立运行的最小单位,也是程序执行的最小单位。任务调度采用的是时间片轮转的抢占式调度方式,而进程是任务调度的最小单位,每个进程有各自独立的内存空间,使得各个进程之间内存地址相互隔离。

后来,随着计算机行业的发展,程序的功能设计越来越复杂,我们的应用中同时发生着多种活动,其中某些活动随着时间的推移会被阻塞,比如网络请求、读写文件(也就是IO操作),我们自然而然地想着能不能把这些应用程序分解成更细粒度、能 准并行运行 多个顺序执行实体,并且这些细粒度的执行实体可以共享进程的地址空间,也就是可以共享程序代码、数据、内存空间等,这样程序设计模型会变得更加简单。

其实很多计算机世界里的技术演变,都是模拟现实世界。比如我们把一个进程当成一个项目,当项目任务变得复杂时,自然想着能不能将项目按照业务、产品、工作方向等分成一个个任务模块,分派给不同人员各自并行完成,再按照某种方式组织起各自的任务成果,最终完成项目。

需要多线程还有一个重要的理由就是:每个进程都有独立的代码和数据空间(程序上下文),程序之间的切换会有较大的开销;线程可以看做轻量级的进程,同一类线程共享代码和数据空间,每个线程都有自己独立的运行栈和程序计数器,线程之间切换的开销小。所以线程的创建、销毁、调度性能远远优于进程。

在引入多线程模型后,进程和线程在程序执行过程中的分工就相当明确了,进程负责分配和管理系统资源,线程负责CPU调度运算,也是CPU切换时间片的最小单位。对于任何一个进程来讲,即便我们没有主动去创建线程,进程也是默认有一个主线程的。

3.它们在Linux内核中实现方式有何不同?

在Linux 里面,无论是进程,还是线程,到了内核里面,我们统一都叫任务(Task),由一个统一的结构 task_struct 进行管理,这个task_struct 数据结构非常复杂,囊括了进程管理生命周期中的各种信息。

 在Linux操作系统内核初始化时会创建第一个进程,即0号创始进程。随后会初始化1号进程(用户进程祖宗:/usr/lib/systemd/systemd),2号进程(内核进程祖宗:[kthreadd]),其后所有的进程线程都是在他们的基础上fork出来的。

 

 我们一般都是通过fork系统调用来创建新的进程,fork 系统调用包含两个重要的事件,一个是将 task_struct 结构复制一份并且初始化,另一个是试图唤醒新创建的子进程。

我们说无论是进程还是线程,在内核里面都是task,管起来不是都一样吗?到底如何区分呢?其实,线程不是一个完全由内核实现的机制,它是由内核态和用户态合作完成的。

 推荐视频

linux服务端的网络并发,详细解读网络io与线程进程关系

【C++后端开发】5000道C++“八股文”,还需要死记硬背吗?90分钟梳理清晰

2023年最新技术图谱,c++后端的8个技术维度,助力你快速成为大牛

免费学习地址:C/C++Linux服务器开发/后台架构师

【文章福利】需要C/C++ Linux服务器架构师学习资料加群812855908(资料包括C/C++,Linux,golang技术,内核,Nginx,ZeroMQ,MySQL,Redis,fastdfs,MongoDB,ZK,流媒体,CDN,P2P,K8S,Docker,TCP/IP,协程,DPDK,ffmpeg,大厂面试题 等)

 

 创建进程的话,调用的系统调用是 fork,会将五大结构 files_struct、fs_struct、sighand_struct、signal_struct、mm_struct 都复制一遍,从此父进程和子进程各用各的数据结构。而创建线程的话,调用的是系统调用 clone,五大结构仅仅是引用计数加一,也即线程共享进程的数据结构。

 

4.所以它们到底有哪些区别?

功能: 进程是操作系统资源分配的基本单位,而线程是任务调度和执行的基本单位

开销: 每个进程都有独立的内存空间,存放代码和数据段等,程序之间的切换会有较大的开销;线程可以看做轻量级的进程,共享内存空间,每个线程都有自己独立的运行栈和程序计数器,线程之间切换的开销小。

运行环境: 在操作系统中能同时运行多个进程;而在同一个进程(程序)中有多个线程同时执行(通过CPU调度,在每个时间片中只有一个线程执行)

创建过程: 在创建新进程的时候,会将父进程的所有五大数据结构复制新的,形成自己新的内存空间数据,而在创建新线程的时候,则是引用进程的五大数据结构数据,但是线程会有自己的私有数据、栈空间。

进程和线程其实在cpu看来都是task_struct结构的一个封装,执行不同task即可,而且在cpu看来就是在执行这些task时候遵循对应的调度策略以及上下文资源切换定义,包括寄存器地址切换,内核栈切换。所以对于cpu而言,进程和线程是没有区别的。

附:我们通常所说的上下文切换具体指什么?

操作系统抽象出一个进程的概念,让应用程序专心于实现自己的业务逻辑既可,对应用程序屏蔽了CPU调度、内存管理等硬件细节,而且在有限的CPU上可以“同时”进行许多个任务。但是它为用户带来方便的同时,也引入了一些额外的开销。

在操作系统中,由于CPU的时间片调度策略,从一个进程切换到另一个进程需要保存当前进程的状态并恢复另一个进程的状态:当前运行任务转为就绪(或者挂起、删除)状态,另一个被选定的就绪任务成为当前任务。上下文切换包括保存当前任务的运行环境,恢复将要运行任务的运行环境。

在上下文切换过程中,CPU会停止处理当前运行的程序,并保存当前程序运行的具体位置以便之后继续运行。从这个角度来看,上下文切换有点像我们同时阅读几本书,在来回切换书本的同时我们需要记住每本书当前读到的页码。

在三种情况下可能会发生上下文切换:中断处理,多任务处理,内核/用户态切换。

在中断处理中,其他程序”打断”了当前正在运行的程序。当CPU接收到中断请求时,会在正在运行的程序和发起中断请求的程序之间进行一次上下文切换。

在多任务处理中,CPU会在不同程序之间来回切换,每个程序都有相应的处理时间片,CPU在两个时间片的间隔中进行上下文切换。

在Linux中进行内核/用户态切换也会进行上下文切换,进行系统调用时,CPU寄存器里原来用户态的指令位置需要先保存起来。接着,为了执行内核态代码,CPU寄存器需要更新为内核态指令的新位置。最后才是跳转到内核态运行内核任务。而系统调用结束后,CPU寄存器需要恢复原来保存的用户态,然后再切换到用户空间,继续运行进程,所以一次系统调用的过程,其实是发生了两次CPU上下文切换。

CPU上下文切换,是保证Linux系统正常工作的核心功能之一,一般情况下不需要我们特别关注。

但过多的上下文切换,会把CPU时间消耗在寄存器、内核栈以及虚拟内存等数据的保存和恢复上,从而缩短进程真正运行的时间,导致系统的整体性能大幅下降。

相关文章:

面试必问:进程和线程的区别(从操作系统层次理解)

1.什么是进程?为什么要有进程? 进程有一个相当精简的解释:进程是对操作系统上正在运行程序的一个抽象。 这个概念确实挺抽象,仔细想想却也挺精准。 我们平常使用计算机,都会在同一时间做许多事,比如边看…...

ModuleNotFoundError: No module named ‘apex‘与 error: legacy-install-failure

ModuleNotFoundError: No module named ‘apex’ ModuleNotFoundError: No module named apex 表示 Python 在搜索模块时无法找到名为 apex 的模块。这通常是因为您没有安装 apex 模块或安装不正确。 apex 是一个针对混合精度训练和优化的 PyTorch 扩展库,您可以通过…...

Python3 VScode 配置

Python3 VScode 配置 在上一章节中我们已经安装了 Python 的环境,本章节我们将介绍 Python VScode 的配置。 准备工作: 安装 VS Code 安装 VS Code Python 扩展 安装 Python 3 安装 VS Code VSCode(全称:Visual Studio Code&…...

VMware 修复了三个身份认证绕过漏洞

Bleeping Computer 网站披露,VMware 近期发布了安全更新,以解决 Workspace ONE Assist 解决方案中的三个严重漏洞,分别追踪为 CVE-2022-31685(认证绕过)、CVE-2022-31686 (认证方法失败)和 CVE-…...

实现一个简单的Database10(译文)

GreatSQL社区原创内容未经授权不得随意使用,转载请联系小编并注明来源。GreatSQL是MySQL的国产分支版本,使用上与MySQL一致。作者: 花家舍文章来源:GreatSQL社区原创 前文回顾 实现一个简单的Database系列 译注:csta…...

CTF-取证题目解析-提供环境

一、安装 官网下载:Volatility 2.6 Release 1、将windows下载的volatility上传到 kali/home 文件夹里面 3、将home/kali/vol刚刚上传的 移动到use/sbin目录里面 mv volatility usr/local/sbin/ 切换到里面 cd /usr/local/sbin/volatility 输入配置环境echo $PAT…...

计算机基础 | 网络篇 | TCP/IP 四层模型

前沿:撰写博客的目的是为了再刷时回顾和进一步完善,其次才是以教为学,所以如果有些博客写的较简陋,是为了保持进度不得已而为之,还请大家多多见谅。 一、OSI 七层模型 参考文章:OSI 和 TCP/IP 网络分层模型…...

实时数据仓库

1 为什么选择kafka? ① 实时写入,实时读取 ② 消息队列适合,其他数据库受不了 2 ods层 1)存储原始数据 埋点的行为数据 (topic :ods_base_log) 业务数据 (topic :ods_base_db) 2)业务数据的有序性&#x…...

leetcode 1250. 检查「好数组」

给你一个正整数数组 nums,你需要从中任选一些子集,然后将子集中每一个数乘以一个 任意整数,并求出他们的和。 假如该和结果为 1,那么原数组就是一个「好数组」,则返回 True;否则请返回 False。 示例 1&…...

JDK动态代理和CGLib动态代理的区别

原文网址:JDK动态代理和CGLib动态代理的区别_IT利刃出鞘的博客-CSDN博客 简介 本文介绍Java中JDK动态代理和CGLib动态代理的区别。 区别概述 项 JDK动态代理 CGLIB动态代理 接口是否需实现 只能代理实现了接口的类。 可以代理没有实现接口的类。 原理 继承…...

Leetcode.1250 检查「好数组」

题目链接 Leetcode.1250 检查「好数组」 Rating : 1983 题目描述 给你一个正整数数组 nums,你需要从中任选一些子集,然后将子集中每一个数乘以一个 任意整数,并求出他们的和。 假如该和结果为 1,那么原数组就是一个「…...

WMS系统推荐,如何选到适合企业的仓库管理系统

市场上有很多WMS系统,但是现在很多仓库管理系统都在使用WMS系统。那么在选择WMS系统时应该考虑什么呢?明确业务发展特征,准确表达能力目标许多物流企业在选择物流管理系统时,往往会被物流管理系统的整体系统所迷惑,在功…...

C语言的期末复习

🌈博客主页:卿云阁 💌欢迎关注🎉点赞👍收藏⭐️留言📝 🌟本文由卿云阁原创! 🙏作者水平很有限,如果发现错误,请留言轰炸哦!万分感谢&a…...

强化学习之DQN论文介绍

强化学习之DQN论文介绍DQN摘要介绍问题特点经验回放相关工作实验算法流程结论DQN 摘要 1.基于Q-learning从高维输入学习到控制策略的卷积神经网络。 2.输入是像素,输出是奖励函数。 3.主要训练、学习Atari 2600游戏,在6款游戏中3款超越人类专家。 介绍 …...

使用luaBridge添加自己的C++脚本插件能力

概述 如果我们有一个应用需要频繁的更改业务逻辑,但是基础功能不变,那么我们可以将基础功能作为底层接口,上层的功能按照脚本方式来编写。很多插件都这样的原理,比如我们的浏览器的JS就这样,小程序也是这样的原理,我们使用C++也很容易实现这样的功能。 lua是最小最精致的…...

再拾起博客

一切要从去年12月27日被裁员的那天说起。 那天是星期二,和平常一样,8点20的闹钟响起,但我习惯性的磨蹭到8点40起床,洗漱完成后9点过几分出门,骑车20多分钟几乎是踩点到的公司,正当我坐在工位准备平复心情切…...

Mybatis流式游标查询-大数据DB查询OOM查询问题

问题场景Mysql数据处理类型分以下三种com.mysql.cj.protocol.a.result.ResultsetRowsStatic:普通查询,将结果集一次性全部拉取到内存com.mysql.cj.protocol.a.result.ResultsetRowsCursor:游标查询,将结果集分批拉取到内存&#x…...

以before为例 完成一个aop代理强化方法案例

观看本文 首先 您需要做好Spring aop的准备工作 具体可以参考我的文章 java Spring aop入门准备工作 首先 我们创建一个包 我这里叫 Aop 然后在Aop包下创建一个类 叫 User 参考代码如下 package Aop;public class User {public void add(){System.out.println("add....…...

好记性不如烂笔头之Java基础复习笔记

未完待续。。。 代码块先于构造方法执行,不管类中有多少个代码块,都会先将所有代码块执行完再执行构造方法和其他方法。类中如果没有自定义的构造方法,那么JVM会提供默认的无参构造方法;如果类中有自定义的构造方法,那…...

MyBatisPlus

这里写目录标题1.MyBatisPlus概述2.MyBatisPlus的开发步骤2.1 MyBatisPlus的CRUD操作2.2 MyBatisPlus的分页查询3.MyBatisPlus的DQL编程控制(封装sql)3.1 条件查询方式3.1.1 条件查询3.1.2 组合条件3.1.3 Null值处理3.2 查询投影-设置【查询字段、分组、分页】3.2.1 查询结果包…...

CentOS下的分布式内存计算Spark环境部署

一、Spark 核心架构与应用场景 1.1 分布式计算引擎的核心优势 Spark 是基于内存的分布式计算框架,相比 MapReduce 具有以下核心优势: 内存计算:数据可常驻内存,迭代计算性能提升 10-100 倍(文档段落:3-79…...

unix/linux,sudo,其发展历程详细时间线、由来、历史背景

sudo 的诞生和演化,本身就是一部 Unix/Linux 系统管理哲学变迁的微缩史。来,让我们拨开时间的迷雾,一同探寻 sudo 那波澜壮阔(也颇为实用主义)的发展历程。 历史背景:su的时代与困境 ( 20 世纪 70 年代 - 80 年代初) 在 sudo 出现之前,Unix 系统管理员和需要特权操作的…...

Spring AI 入门:Java 开发者的生成式 AI 实践之路

一、Spring AI 简介 在人工智能技术快速迭代的今天,Spring AI 作为 Spring 生态系统的新生力量,正在成为 Java 开发者拥抱生成式 AI 的最佳选择。该框架通过模块化设计实现了与主流 AI 服务(如 OpenAI、Anthropic)的无缝对接&…...

(转)什么是DockerCompose?它有什么作用?

一、什么是DockerCompose? DockerCompose可以基于Compose文件帮我们快速的部署分布式应用,而无需手动一个个创建和运行容器。 Compose文件是一个文本文件,通过指令定义集群中的每个容器如何运行。 DockerCompose就是把DockerFile转换成指令去运行。 …...

JAVA后端开发——多租户

数据隔离是多租户系统中的核心概念,确保一个租户(在这个系统中可能是一个公司或一个独立的客户)的数据对其他租户是不可见的。在 RuoYi 框架(您当前项目所使用的基础框架)中,这通常是通过在数据表中增加一个…...

HubSpot推出与ChatGPT的深度集成引发兴奋与担忧

上周三,HubSpot宣布已构建与ChatGPT的深度集成,这一消息在HubSpot用户和营销技术观察者中引发了极大的兴奋,但同时也存在一些关于数据安全的担忧。 许多网络声音声称,这对SaaS应用程序和人工智能而言是一场范式转变。 但向任何技…...

tomcat指定使用的jdk版本

说明 有时候需要对tomcat配置指定的jdk版本号,此时,我们可以通过以下方式进行配置 设置方式 找到tomcat的bin目录中的setclasspath.bat。如果是linux系统则是setclasspath.sh set JAVA_HOMEC:\Program Files\Java\jdk8 set JRE_HOMEC:\Program Files…...

人工智能 - 在Dify、Coze、n8n、FastGPT和RAGFlow之间做出技术选型

在Dify、Coze、n8n、FastGPT和RAGFlow之间做出技术选型。这些平台各有侧重,适用场景差异显著。下面我将从核心功能定位、典型应用场景、真实体验痛点、选型决策关键点进行拆解,并提供具体场景下的推荐方案。 一、核心功能定位速览 平台核心定位技术栈亮…...

在鸿蒙HarmonyOS 5中使用DevEco Studio实现指南针功能

指南针功能是许多位置服务应用的基础功能之一。下面我将详细介绍如何在HarmonyOS 5中使用DevEco Studio实现指南针功能。 1. 开发环境准备 确保已安装DevEco Studio 3.1或更高版本确保项目使用的是HarmonyOS 5.0 SDK在项目的module.json5中配置必要的权限 2. 权限配置 在mo…...

相关类相关的可视化图像总结

目录 一、散点图 二、气泡图 三、相关图 四、热力图 五、二维密度图 六、多模态二维密度图 七、雷达图 八、桑基图 九、总结 一、散点图 特点 通过点的位置展示两个连续变量之间的关系,可直观判断线性相关、非线性相关或无相关关系,点的分布密…...