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

Linux中进程和线程区别

进程在内核中的描述符 task_struct 结构:

struct task_struct {// 进程idpid_t    pid;// 用于标识线程所属的进程 pidpid_t    tgid;// 进程打开的文件信息struct files_struct  *files;// 内存描述符表示进程虚拟地址空间struct mm_struct  *mm;.......... 省略 .......
}

在进程描述符 task_struct 结构中,有一个专门描述进程虚拟地址空间的内存描述符 mm_struct 结构,这个结构体中包含了前边几个小节中介绍的进程虚拟内存空间的全部信息。

每个进程都有唯一的 mm_struct 结构体,也就是前边提到的每个进程的虚拟地址空间都是独立,互不干扰的。

通过  fork() 函数创建子进程:

copy_mm  函数首先会将父进程的虚拟内存空间 current->mm 赋值给指针 oldmm。然后通过 dup_mm 函数将父进程的虚拟内存空间以及相关页表拷贝到子进程的 mm_struct 结构中。最后将拷贝出来的 mm_struct 赋值给子进程的 task_struct 结构。

通过 fork() 函数创建出的子进程,它的虚拟内存空间以及相关页表相当于父进程虚拟内存空间的一份拷贝,直接从父进程中拷贝到子进程中。

通过 vfork 或者 clone 系统调用创建出的子进程:

首先会设置 CLONE_VM 标识,这样来到 copy_mm 函数中就会进入  if (clone_flags & CLONE_VM)  条件中,在这个分支中会将父进程的虚拟内存空间以及相关页表直接赋值给子进程。这样一来父进程和子进程的虚拟内存空间就变成共享的了。也就是说父子进程之间使用的虚拟内存空间是一样的,并不是一份拷贝。

进程和线程:

子进程共享了父进程的虚拟内存空间,这样子进程就变成了我们熟悉的线程,是否共享地址空间几乎是进程和线程之间的本质区别。Linux 内核并不区别对待它们,线程对于内核来说仅仅是一个共享特定资源的进程而已

内核线程和用户态线程:

内核线程和用户态线程的区别就是内核线程没有相关的内存描述符 mm_struct ,内核线程对应的 task_struct 结构中的 mm 域指向 Null,所以内核线程之间调度是不涉及地址空间切换的。

当一个内核线程被调度时,它会发现自己的虚拟地址空间为 Null,虽然它不会访问用户态的内存,但是它会访问内核内存,聪明的内核会将调度之前的上一个用户态进程的虚拟内存空间 mm_struct 直接赋值给内核线程,因为内核线程不会访问用户空间的内存,它仅仅只会访问内核空间的内存,所以直接复用上一个用户态进程的虚拟地址空间就可以避免为内核线程分配 mm_struct 和相关页表的开销,以及避免内核线程之间调度时地址空间的切换开销。

父进程与子进程的区别,进程与线程的区别,以及内核线程与用户态线程的区别其实都是围绕着这个 mm_struct 展开的。

参考:一步一图带你深入理解 Linux 虚拟内存管理

相关文章:

  • vue实现一个简单的审批绘制功能
  • 数据提取的奥秘
  • c++初级-2-引用
  • uniapp 使用cavans 生成海报
  • 使用docker搭建squid和ss5
  • Docker Compose 一键快速部署 RocketMQ
  • SpringBoot3集成MyBatisPlus
  • 【鸿蒙学习笔记】Image迭代完备
  • 难道 Java 已经过时了?
  • Android 内存原理详解以及优化(二)
  • 边缘网关在实际应用中的价值与挑战-天拓四方
  • 66.前端接口调用返回400的错误
  • OpenBMB × Hugging Face × THUNLP,大模型课开班丨伙伴活动推荐
  • P3374 【模板】树状数组 1
  • 【C++】开源:量化金融计算库QuantLib配置与使用
  • CSS实用技巧
  • DOM的那些事
  • ES6, React, Redux, Webpack写的一个爬 GitHub 的网页
  • Git学习与使用心得(1)—— 初始化
  • Java知识点总结(JDBC-连接步骤及CRUD)
  • linux学习笔记
  • nginx 负载服务器优化
  • php ci框架整合银盛支付
  • PHP 程序员也能做的 Java 开发 30分钟使用 netty 轻松打造一个高性能 websocket 服务...
  • Python_网络编程
  • SQLServer之创建数据库快照
  • TiDB 源码阅读系列文章(十)Chunk 和执行框架简介
  • 官方解决所有 npm 全局安装权限问题
  • 基于Javascript, Springboot的管理系统报表查询页面代码设计
  • 基于webpack 的 vue 多页架构
  • 紧急通知:《观止-微软》请在经管柜购买!
  • 马上搞懂 GeoJSON
  • 前端性能优化--懒加载和预加载
  • 深度解析利用ES6进行Promise封装总结
  • 学习Vue.js的五个小例子
  • 做一名精致的JavaScripter 01:JavaScript简介
  • # 执行时间 统计mysql_一文说尽 MySQL 优化原理
  • #NOIP 2014# day.1 T2 联合权值
  • (2024最新)CentOS 7上在线安装MySQL 5.7|喂饭级教程
  • (pytorch进阶之路)扩散概率模型
  • (附源码)springboot社区居家养老互助服务管理平台 毕业设计 062027
  • (十一)JAVA springboot ssm b2b2c多用户商城系统源码:服务网关Zuul高级篇
  • (四)七种元启发算法(DBO、LO、SWO、COA、LSO、KOA、GRO)求解无人机路径规划MATLAB
  • (一)python发送HTTP 请求的两种方式(get和post )
  • (一)Thymeleaf用法——Thymeleaf简介
  • (转)甲方乙方——赵民谈找工作
  • (转)我也是一只IT小小鸟
  • *Algs4-1.5.25随机网格的倍率测试-(未读懂题)
  • .NET Framework与.NET Framework SDK有什么不同?
  • .NET Micro Framework初体验
  • .net 怎么循环得到数组里的值_关于js数组
  • .net生成的类,跨工程调用显示注释
  • .NET使用HttpClient以multipart/form-data形式post上传文件及其相关参数
  • .Net组件程序设计之线程、并发管理(一)
  • 。Net下Windows服务程序开发疑惑