概念
在学习操作系统的过程中,"进程"、"线程"概念其实很模糊。不同的上下文中,该名称指代的概念很可能是不同的,概念的不清晰为学习和沟通带来障碍,所以,在最开始我们先对齐概念。
很多书籍、文章里会这样来定义进程和线程:
- 进程:资源分配的最小单位;
- 线程:程序执行的最小单位;
其实这样的描述依然是不够具体的。
一个执行中的程序,其实是由一组资源和(一个或者多个)执行实体组成的,每个执行实体需要自己执行过程中所必须的独有资源,所有的执行实体共享可共享资源。
这里的执行实体,就是线程;这里的执行实体和共享资源,就是进程。
进程中的资源
-
(用户)虚拟地址空间
- 栈:(运行中的)局部变量、函数参数、返回地址等
- 堆:动态分配的内存
- BSS 段:未初始化或初始值为 0 的全局变量和静态局部变量
- 数据段:已初始化且初始值非 0 的全局变量和静态局部变量
- 代码段:可执行代码、字符串字面值、只读变量
- 文件描述符(File Descriptor)
-
信号相关
- 信号处理程序设置(这个设置可以在每个线程中设置,但是整个进程的所有线程对该设置共享,以最后一次设置为准)
- 信号屏蔽设置
- 信号量(这里的信号量跟上面的信号是两码事,上面的信号指的是中断,这里的信号量指的是进程间通信的一种机制)
上述的所有资源中,加粗标记的为每个线程中独有的资源,未加粗的为所有线程共享的资源。
关于虚拟地址空间,这里有张图比较方便我们理解。这张图的详细解释
很多文章中会提到以下几个东西:
- 子进程
-
计数器和寄存器
- 程序计数器(PC)
-
寄存器
- 指令寄存器(IR)
- 地址寄存器
这其中,进程关系在 Linux 中其实是使用独立的结构体进行存储的,通过内核提供的方法来获取,本质上不应该算是某种资源。其主体是内核 task_struct,后续我们会展开详细描述。
而计数器和寄存器是体系结构相关的硬件实现,处于执行中的执行实体(线程)会使用这些硬件,所以也不能算是某种资源。
该段落拓展阅读:
Linux 对进程和线程的实现(5.0.0 内核)
Linux 只有一个结构体来描述进程/线程—— task_struct,该文件位于 /linux/include/linux/sched.h
。
这一结构体中有字段指向/描述相关资源和相互之间的关系,因而,该结构体更应该认为是一个“线程结构体”,而“线程结构体”上的这些对于相关资源和相互之间关系的描述,则构成了“进程”。
后面的笔记中会有对 task_struct 结构体的详细分析。
**粗体** _斜体_ [链接](http://example.com) `代码` - 列表 > 引用
。你还可以使用@
来通知其他用户。