发布网友 发布时间:2022-04-24 10:43
共1个回答
热心网友 时间:2023-10-10 11:11
所谓进程其实就是执行中的程序而已,和静态的程序相比,进程是一个运行态的实体,拥有各种各样的资源:地址空间(未必使用全部地址空间,而是排布在地址空间上的一段段的memory mappings)、打开的文件、pending的信号、一个或者多个thread of execution,内核中数据实体(例如一个或者多个task_struct实体),内核栈(也是一个或者多个)等。针对进程,我们使用进程ID,也就是pid(process ID)。通过getpid和getppid可以获取当前进程的pid以及父进程的pid。
进程中的thread of execution被称作线程(thread),线程是进程中活跃状态的实体。一方面进程中所有的线程共享一些资源,另外一方面,线程又有自己专属的资源,例如有自己的PC值,用户栈、内核栈,有自己的hw context、调度策略等等。我们一般会说进程调度什么的,但是实际上线程才是是调度器的基本单位。对于Linux内核,线程的实现是一种特别的存在,和经典的unix都不一样。在linux中并不区分进程和线程,都是用task_struct来抽象,只不过支持多线程的进程是由一组task_struct来抽象,而这些task_struct会共享一些数据结构(例如内存描述符)。我们用thread ID来唯一标识进程中的线程,POSIX规定线程ID在所属进程中是唯一的,不过在linux kernel的实现中,thread ID是全系统唯一的,当然,考虑到可移植性,Application software不应该假设这一点。在用户空间,通过gettid函数可以获取当前线程的thread ID。对于单线程的进程,process ID和thread ID是一样的,对于支持多线程的进程,每个线程有自己的thread ID,但是所有的线程共享一个PID。
为了方便shell进行Job controll,我们需要把一组进程组织起来形成进程组。关于这方面的概念,在进程和终端文档中描述的很详细,这里就不赘述了。为了标识进程组,我们需要引入进程组ID的概念。我们一般把进程组中的第一个进程的ID作为进程组的ID,进程组中的所有进程共享一个进程组ID。在用户空间,通过setpgid、getpgid、setpgrp和getpgrp等接口函数可以访问process group ID。
经过thread ID、process ID、process group ID的层层递进,我们终于来到最顶层的ID,也就是session ID,这个ID实际上是用来标识计算机系统中的一次用户交互过程:用户登录入系统,不断的提交任务(即Job或者说是进程组)给计算机系统并观察结果,最后退出登录,销毁该session。关于session的概念,在进程和终端文档中描述的也很详细,大家可以参考那份文档,这里就不赘述了。在用户空间,我们可以通过getsid、setsid来操作session ID。
用户空间如何看到process ID
我们用下面这个block diagram来描述用户空间和内核空间如何看待process ID的: