咨询干货

了解优化推广技术相关资讯

既然在Linux中程序不是进程,那么什么才算是进程?线程呢?

2019-08-03来自网络作者: 嵌入式时代

C语言程序员编写的代码可以编译为程序,程序通常存放在磁盘等存储介质中。在 Linux 中,处于运行期的程序被称作“进程”。

既然在Linux中程序不是进程,那么什么才算是进程?线程呢?

处于运行期的程序被称作“进程”

进程

虽说进程是处于运行期的程序,但是进程并不仅仅局限于可执行的C语言代码(Linux 称其为代码段,text section),它还包括其他资源,例如用于存放全局变量的数据段(data section)、具有内存映射的内存地址空间、要处理的数据、挂起的信号、打开的文件,可能还会包括多个执行线程等等。

事实上,进程是 Linux 操作系统抽象概念的最基本的一种,Linux 最基础最重要的工作之一就是管理系统中繁杂的各种进程。
既然在Linux中程序不是进程,那么什么才算是进程?线程呢?

“执行线程”通常被简称为“线程”

上面提到的“执行线程”通常被简称为“线程”,它被进程包含,同一个进程可能有多个线程,每个线程都有自己独立的程序计数器、进程栈以及相关的进程寄存器。虽说 Linux 内核管理的是进程,但其实最小的调度单位是线程。

早期传统的 Unix 系统中,一个进程只能包含一个线程,所以当时进程调度和线程调度其实结果是一致的。

线程

如今的操作系统中,进程包含多个线程是非常常见的。Linux 与一些其他操作系统不同,它对进程和线程并不明确区分,对于 Linux 来说,线程不过是一种比较特殊的进程而已。

既然在Linux中程序不是进程,那么什么才算是进程?线程呢?

线程不过是一种比较特殊的进程而已

包括 Linux,现代操作系统一般都会为进程提供两种虚拟机制:虚拟处理器和虚拟内存。读者应注意“虚拟”一词,多个进程可能共同使用一个 CPU 和内存,但是“虚拟机制”会让进程活在楚门的世界一样,自以为自己独占 CPU 和全部内存。

应注意,线程之间可以共享虚拟内存,但是它们仍然拥有各自的虚拟 CPU。

到这里,读者应该明白了,编译器生成的C语言程序本身并不是进程。进程实际上是处于运行期的程序,与相关资源的总和。

事实上,无论是程序不同,还是执行时的数据不同,都会产生不同的进程。举例来说,同样一个C语言程序,是可以产生两个不同的进程的——它们的运行资源可能是不同的。反过来也是一样的,多个不同的进程也可以共享同一份资源,例如打开同一个文件,映射同一块内存空间等。

既然在Linux中程序不是进程,那么什么才算是进程?线程呢?

进程实际上是处于运行期的程序,与相关资源的总和

进程的产生与消亡

可能有读者认为,直接执行一个程序不就产生新进程了吗?这样说没有错,但是不够本质。在 Linux 操作系统中,通过 fork() 系统调用可以复制现有进程,并产生新进程。调用 fork() 的进程一般被称作“父进程”,而 fork() 产生的新进程则被称作“子进程”。

fork() 调用结束时,会从 Linux 内核返回两次:一次返回到父进程,父进程恢复运行。一次返回到子进程,子进程开始执行,在这之后,父子进程的进程资源彼此隔离,不再共享。

既然在Linux中程序不是进程,那么什么才算是进程?线程呢?

fork() 调用结束时,会从 Linux 内核返回两次

不过一般来说,如果有需求创建新的进程,一般都是为了执行不同的新的程序。这一过程通过 exec() 函数族可以方便实现,它们可以为新程序创建新的地址空间,然后加载程序执行。

Linux 操作界面的 shell 终端其实也是一个进程,通过 shell 输入的执行新程序命令(如 ./a.out )产生的新进程其实都是对应 shell 终端的子进程。

程序既然有新生,也就会有死亡,程序运行结束后,通过 exit() 系统调用退出运行,这个函数会杀死进程,并且将其占用的资源释放,通知其父进程“死亡信息”。父进程则可以通过 wait() 函数族接收子进程的“死亡信息”,并着手为子进程做后续的“收尸工作”,避免子进程编程“僵尸进程(zombie)”。

“僵尸进程”很难杀死,但是留着“僵尸进程”又会白白浪费系统资源。
既然在Linux中程序不是进程,那么什么才算是进程?线程呢?

点个赞再走吧

欢迎在评论区一起讨论,质疑。文章都是手打原创,每天最浅显的介绍C语言、linux等嵌入式开发,喜欢我的文章就关注一波吧,可以看到最新更新和之前的文章哦。

声明:本站发布的内容以原创、转载、分享网络内容为主,如有侵权,请联系电话:021-51697771-8029,邮箱:mj@cndns.com,我们将会在第一时间删除。文章观点不代表本站立场,如需处理请联系我们。