进程概念和结构
1.进程描述符 task_struct
每个独立进程都有一个这个结构体,大小大概1.7kb, 定义在<linux/sched.h>文件中
任务队列就是由很多个task_struct 组成的,进程是被fork出来的,所有进程都有父进程(创建它的进程),Linux通过slab分配器分配一个task_struct结构,每当新的进程被创建,会在内核栈顶中分配一个新的thread_info <asm/thread_info.h>,这里会有指向真实进程描述符task_struct的指针*task。
下面介绍task_struct里面的成员
(1)进程号pid
内核通过唯一的进程号PID来识别进程,是int类型,系统最大pid默认32768,但是可以通过/proc/sys/kernel/pid_max来修改.
(2)进程状态state
共有5种状态
#define TASK_RUNNING 0
#define TASK_INTERRUPTIBLE 1
#define TASK_UNINTERRUPTIBLE 2
#define __TASK_STOPPED 4
#define __TASK_TRACED 8
最主要是前四种,第一种就是起来了随时可以被调度或者正在被执行,第二个是正在阻塞中或睡眠,锁或者硬终端中,等处理完了就会回到running状态,,但是可以被更高级别的信号随时唤醒,第三个是不能被信号唤醒的,也就是操作不可被中断的,用的比较少。 第四个,进程被停止执行,当进程接收到SIGSTOP、SIGTTIN、SIGTSTP或者SIGTTOU信号之后就会进入该状态,第五个是被追踪或者debug的状态吗,暂时不知道是干啥的。
//进程在被interrupt的时候会从任务队列中拿出去,放在等待队列里,这个稍后会说。
内核使用set_task_state(task, state) <linux/sched.h>来设置task的状态
2.进程上下文
用户态进程在系统调用或者异常的时候会陷入内核,这时候内核态进程执行是代表用户进程执行,虽然在不同的地址空间但还是代表用户进程执行,因为退出这个系统调用的时候会回到用户进程继续执行,但是有时候如果是硬件中断直接在内核执行的时候,是不代表任何进程执行的。
3.进程家族树
每个进程一定有自己的父进程,所有的进程都是第一个init进程(1号进程),task_struct 有一个parent指向父进程的进程描述符。
任务队列是一个双向链表,可以通过next_task和prev_task指针来访问整个队列。
下一篇:进程创建