台式机&硬件面试官:换人!他连进程线程协程这几个特点都说不出


很早之前就在构思这篇文章的主题 , 进程线程可以说是操作系统基础 , 看过很多关于这方面知识的文章都是纯理论讲述 , 编程新手有些难以直接服用 。
于是写下这篇文章 , 用图解的形式带你学习和掌握进程、线程、协程 , 文字力求简单明了 , 对于复杂概念做到一个概念一张图解 , 即使你是编程小白也能看的明明白白 , 妈妈再也不用担心你的学习 。
台式机&硬件面试官:换人!他连进程线程协程这几个特点都说不出
本文插图
Go 基础教程系列教程更新已接近尾声 , 对 Go 语言学习感兴趣但还没看过的的同学 , 可以点击这个传送门:
Go 基础教程接下来会进入并发编程和 Go 协程部分 , 为了更好的理解这部分内容 , 带大家先了解 Linux 系统基础和进程、线程以及协程的差异与特点 。
在操作系统课程的学习中 , 很多人对进程线程有大体的认识 , 但操作系统教材更偏向于理论叙述 , 本文会结合 Linux 系统实现分析 , 更加印象深刻 。
同时 , 大部分人都接触进程和线程比较多 , 对协程知之甚少 , 然而最近协程并发编程技术火热起来 , 希望读完本文你对协程也有一个基本的了解 。
话不多说 , 我们马上进入本文的学习 。
进程
关于进程和内存管理我之前有一篇文章单独讲解过 , 感兴趣的同学点这里《》 这里再挑选一部分和本文相关的内容学习 , 温故而知新 。
首先还是说下「程序」的概念 , 程序是一些保存在磁盘上的指令的有序集合 , 是静态的 。 进程是程序执行的过程 , 包括了动态创建、调度和消亡的整个过程 , 进程是程序资源管理的最小单位 。
进程与资源
那么进程都管理哪些资源呢?通常包括内存资源、IO资源、信号处理等部分 。
台式机&硬件面试官:换人!他连进程线程协程这几个特点都说不出
本文插图

程序和进程
篇幅有限着重说一下内存管理 , 进程运行起来必然会涉及到对内存资源的管理 。 内存资源有限 , 操作系统采用虚拟内存技术 , 把进程虚拟地址空间划分成用户空间和内核空间 。
地址空间
4GB 的进程虚拟地址空间被分成两部分:用户空间和内核空间
台式机&硬件面试官:换人!他连进程线程协程这几个特点都说不出
本文插图
用户空间内核空间 用户空间
用户空间按照访问属性一致的地址空间存放在一起的原则 , 划分成 5个不同的内存区域 。 访问属性指的是“可读、可写、可执行等。
代码段
代码段是用来存放可执行文件的操作指令 , 可执行程序在内存中的镜像 。 代码段需要防止在运行时被非法修改 , 所以只准许读取操作 , 它是不可写的 。
数据段
数据段用来存放可执行文件中已初始化全局变量 , 换句话说就是存放程序静态分配的变量和全局变量 。
BSS段
BSS段包含了程序中未初始化的全局变量 , 在内存中 bss 段全部置零 。
堆 heap
堆是用于存放进程运行中被动态分配的内存段 , 它的大小并不固定 , 可动态扩张或缩减 。 当进程调用malloc等函数分配内存时 , 新分配的内存就被动态添加到堆上(堆被扩张);当利用free等函数释放内存时 , 被释放的内存从堆中被剔除(堆被缩减)
栈 stack
栈是用户存放程序临时创建的局部变量 , 也就是函数中定义的变量(但不包括 static 声明的变量 , static意味着在数据段中存放变量) 。 除此以外 , 在函数被调用时 , 其参数也会被压入发起调用的进程栈中 , 并且待到调用结束后 , 函数的返回值也会被存放回栈中 。 由于栈的先进后出特点 , 所以栈特别方便用来保存/恢复调用现场 。 从这个意义上讲 , 我们可以把堆栈看成一个寄存、交换临时数据的内存区 。


推荐阅读