什么是进程?
内核观点:担当分配系统资源(CPU时间,内存)的实体。
进程的两个基本元素是程序代码(可能被执⾏相同程序的其他进程共享)和代码相关联的
数据集。进程是⼀种动态描述,但是并不代表所有的进程都在运行。(进程在内存中因策
略或调度需求,会处于各种状态)
⼴义上,所有的进程信息被放在⼀个叫做进程控制块的数据结构中,可以理解为进程属性
的集合。
进程控制块:
每个进程在内核中都有⼀一个进程控制块
(PCB)
来维护进程相关的信息
,Linux
内核的
进程控制块是
task_struct
结构体。现在我们全⾯面了解⼀一下其中都有哪些信息
在linux 中每一个进程都由task_struct 数据结构来定义. task_struct就是我们通常所说的PCB.她是对进程控制的唯一手段也是最有效的手段. 当我们调用fork() 时, 系统会为我们产生一个task_struct结构。然后从父进程,那里继承一些数据, 并把新的进程插入到进程树中, 以待进行进程管理。因此了解task_struct的结构对于我们理解任务调度(在linux 中任务和进程是同一概念)的关键。
在进行剖析task_struct的定义之前,我们先按照我们的理论推一下它的结构:
1、进程状态 ,将纪录进程在等待,运行,或死锁
2、调度信息, 由哪个调度函数调度,怎样调度等
3、进程的通讯状况
4、因为要插入进程树,必须有联系父子兄弟的指针, 当然是task_struct型
5、时间信息, 比如计算好执行的时间, 以便cpu 分配
6、标号 ,决定改进程归属
7、可以读写打开的一些文件信息
8、 进程上下文和内核上下文
9、处理器上下文
10、内存信息
查找task_struct指令如下:
struct task_struct {
volatile long state; /* -1 不运行, 0 运行, >0 停止*/
void *stack;
atomic_t usage;
unsigned int flags; //每个进程的标志,
unsigned int ptrace;
int lock_depth; /* 仓库锁深度*/
int prio, static_prio, normal_prio;
unsigned int rt_priority;
const struct sched_class *sched_class;
struct sched_entity se;
struct sched_rt_entity rt;
unsigned char fpu_counter;
unsigned int policy;
cpumask_t cpus_allowed;
struct list_head tasks;
struct plist_node pushable_tasks;
struct mm_struct *mm, *active_mm;
int exit_state;
int exit_code, exit_signal;
int pdeath_signal; /* 当父进程死亡信号发送*/
unsigned int personality;
unsigned did_exec:1;
unsigned in_execve:1; /* 告诉lsm过程做一个execve */
unsigned in_iowait:1;
unsigned sched_reset_on_fork:1; /* 恢复到默认优先级*/
pid_t pid;
pid_t tgid;
struct task_struct *real_parent; /*返回父进程*/
struct task_struct *parent; /* 指向其父进程,当它终止时,必须向它的父进程发送信号,
它的值通常和real_parent相同*/
struct list_head children;
struct list_head sibling; /*链接在兄弟链表*/
struct task_struct *group_leader; /* 指向头进程*/
struct list_head ptraced;
struct list_head ptrace_entry;
struct pid_link pids[PIDTYPE_MAX];
struct list_head thread_group;
struct completion *vfork_done; //供fork()使用
int __user *set_child_tid;
int __user *clear_child_tid;
//cpu时间信息
cputime_t utime, stime, utimescaled, stimescaled;
cputime_t gtime;
cputime_t prev_utime, prev_stime;
unsigned long nvcsw, nivcsw; /* 上下文切换项*/
struct timespec start_time; /* 单调的时间*/
struct timespec real_start_time; /* 引导建立时间*/
/* mm断层和交换信息:这可以说可以视为mm-specific或表*/
unsigned long min_flt, maj_flt;
struct task_cputime cputime_expires;
struct list_head cpu_timers[3];
/* 进程的凭证*/
const struct cred *real_cred; /* 客观和真实的主观任务的凭据*/
const struct cred *cred; /* 有效凭证(重写的)主观任务(COW) */
struct mutex cred_guard_mutex; /* 防止外部影响凭证计算(notably. ptrace) */
struct cred *replacement_session_keyring;
int link_count, total_link_count
/* CPU-specific这个任务的状态*/
struct thread_struct thread;
/* 文件系统信息*/
struct fs_struct *fs;
/* 打开文件信息*/
struct files_struct *files;
struct files_struct *files;
/* 域名*/
struct nsproxy *nsproxy;
/* 信号句柄*/
struct signal_struct *signal;
struct sighand_struct *sighand;
sigset_t blocked, real_blocked;
sigset_t saved_sigmask; /* 如果恢复set_restore_sigmask()使用*/
struct sigpending pending;
unsigned long sas_ss_sp;
size_t sas_ss_size;
int (*notifier)(void *priv);
void *notifier_data;
sigset_t *notifier_mask;
struct audit_context *audit_context;
seccomp_t seccomp;
/* 线程组跟踪*/
u32 parent_exec_id;
u32 self_exec_id;
spinlock_t alloc_lock;
/* π的保护数据结构:: */
spinlock_t pi_lock;
/* 日志文件系统信息*/
void *journal_info;
/* 堆块设备信息*/
struct bio *bio_list, **bio_tail;
/* VM 堆*/
struct reclaim_state *reclaim_state;
struct backing_dev_info *backing_dev_info;
struct io_context *io_context;
unsigned long ptrace_message;
siginfo_t *last_siginfo; /* ptrace使用 */
struct task_io_accounting ioac;
};