进程:程序动态执行的过程, 在执行、运行的过程中,需要一定的资源比如:运行内存、CPU时间、磁盘、网络等
进程不等于程序,进程是程序动态执行的过程,而程序则是静态的存储在磁盘中的。
1.进程的组成a
2.进程的组成b
每个进程在运行时都有一个自己的 “CPU上下文”(硬件上下文)
eip : 32位操作系统,cpu中的寄存器, 存储cpu下一条要执行的指令
rip : 64位操作系统,cpu中的寄存器, 存储cpu下一条要执行的指令
进程中,肯定要知道下一条需要执行“ 指令 ”的内存地址,这个内存地址存储在cpu的 “程序计数器” 中
小总结:
3.进程的组成c
站在进程的角度, 每个进程都觉得自己有一颗CPU,真是没谁了~~
时分共享技术的实现,通过“时钟中断(异常号=32)”来实现
进程的组成大总结: 在Linux操作系统内核中,把每个进程都抽象成一个task_struct的结构体它包含了上面描述的那些变量
task_struct结构体中的变量属性:
//标志信息
pid_t pid; // 进程ID
pid_t tgid; // 线程组ID(进程的主线程ID)
struct task_struct *group_leader; // 线程组的领头线程
//亲缘关系———维护"进程之间的关系",是父子,还是兄弟
struct task_struct __rcu *real_parent; // 真实父进程(创建该进程的原始父进程)
struct task_struct __rcu *parent; // 当前父进程(接收SIGCHLD信号的进程)
struct list_head children; // 子进程链表头
struct list_head sibling; // 兄弟进程链表节点
//进程状态信息
volatile long state; // 进程当前状态
int exit_state; // 进程退出状态(退出时的具体状态)
unsigned int flags; // 进程标志位
//文件 & 文件系统 信息
struct fs_struct *fs; // 文件系统信息(当前目录、根目录等。fs包含的目录信息)
struct files_struct *files; // 打开文件表(files管理打开的文件描述符)
//内存管理 信息
struct mm_struct *mm; // 进程内存管理描述符(mm管理进程的虚拟内存空间)
//内核栈 信息
struct thread_info thread_info; // 线程相关信息
void *stack; // 内核栈指针
//信号处理 相关信息
struct signal_struct *signal; // 进程共享信号处理结构
struct sighand_struct *sighand; // 信号处理函数表
sigset_t blocked; // 被阻塞的信号集
sigset_t real_blocked; // 临时阻塞信号集(用于rt_sigtimedwait)
sigset_t saved_sigmask; // 保存的信号掩码(用于TASK_RUNNING状态切换)
struct sigpending pending; // 待处理信号队列
unsigned long sas_ss_sp; // 信号处理备用栈指针
size_t sas_ss_size; // 信号处理备用栈大小
unsigned int sas_ss_flags; // 信号处理栈标志
//进程权限信息
const struct cred __rcu *read_cred; // 读取权限凭证
const struct cred __rcu *cred; // 当前有效权限凭证
//运行统计信息
u64 utime; // 用户态消耗的CPU时间
u64 stime; // 内核态消耗的CPU时间
unsigned long nvcsw; // 自愿(voluntary)上下文切换计数
unsigned long nivcsw; // 非自愿(involuntary)上下文切换计数
u64 start_time; // 进程启动时间,不包含睡眠时间
u64 real_start_time; // 进程启动时间,包含睡眠时间
//进程调度信息
int on_rq; // 是否在运行队列上(0-不在,1-在)
int prio; // 动态优先级
int static_prio; // 静态优先级
int normal_prio; // 基于静态优先级和调度策略计算的标准优先级
unsigned int rt_priority; // 实时进程优先级
const struct sched_class *sched_class; // 调度器类
struct sched_entity se; // 普通调度实体
struct sched_rt_entity rt; // 实时调度实体
struct sched_dl_entity dl; // 截止时间调度实体
unsigned int policy; // 调度策略(SCHED_NORMAL, SCHED_FIFO, SCHED_RR等)
int nr_cpus_allowed; // 进程可运行的CPU数量
cpumask_t cpus_allowed; // 进程可运行的CPU掩码(cpus_allowed限制进程只能在特定CPU上运行)
struct sched_info sched_info; // 调度统计信息
进程与进程之间的小关系:
4. Linux操作系统中的 0号进程、1号进程、2号进程
0号进程(idle进程):它是内核进程,所有进程的祖先,由于历史原因也叫"swapper进程"
- 配置实时时钟
- 挂载根文件系统
- 创建init进程(1号进程)
- 创建kthreadd进程(2号进程)
| 内核进程 | 普通进程 |
| 只运行在“内核态” | 既可以运行在“内核态”,也可以运行在“用户态” |
| 只能使用大于PAGE_OFFSET的虚拟地址空间 | 可以使用所有的虚拟地址空间(运行在内核态就用内核的虚拟地址空间、运行在用户态就用用户态虚拟地址空间) |