进程的描述PCB
task_struct——PCB的一种,在linux中描述进程的结构体叫做task_struct.
task_struct内容分类:
- 标识符:描述本进程的唯一标识符,用来区别其他进程
- 状态:任务状态,推出代码,退出信号等
- 优先级:相对于其他进程的优先级
- 程序计数器:程序中即将被执行的下一条指令的地址
- 内存指针:包括程序代码和进程相关数据的指针,还有和其他进程共享的内存块的指针
- 上下文数据:进程执行时处理器的寄存器中欧给的数据
- I/O状态信息:包括显示的I/O请求,分配的进程I/O设备和进程使用的文件列表
- 记账信息:可能包括处理器时间总和,使用的时钟总和,时间限制,记帐号等
- 其他信息
源代码:
1 struct task_struct { 2 volatile long state; /* -1 unrunnable, 0 runnable, >0 stopped */ 3 void *stack; 4 atomic_t usage; 5 unsigned int flags; /* per process flags, defined below */ 6 unsigned int ptrace; 7 8 int lock_depth; /* BKL lock depth */ 9 10 #ifdef CONFIG_SMP 11 #ifdef __ARCH_WANT_UNLOCKED_CTXSW 12 int oncpu; 13 #endif 14 #endif 15 16 int prio, static_prio, normal_prio; 17 unsigned int rt_priority; 18 const struct sched_class *sched_class; 19 struct sched_entity se; 20 struct sched_rt_entity rt; 21 22 #ifdef CONFIG_PREEMPT_NOTIFIERS 23 /* list of struct preempt_notifier: */ 24 struct hlist_head preempt_notifiers; 25 #endif 26 27 /* 28 * fpu_counter contains the number of consecutive context switches 29 * that the FPU is used. If this is over a threshold, the lazy fpu 30 * saving becomes unlazy to save the trap. This is an unsigned char 31 * so that after 256 times the counter wraps and the behavior turns 32 * lazy again; this to deal with bursty apps that only use FPU for 33 * a short time 34 */ 35 unsigned char fpu_counter; 36 #ifdef CONFIG_BLK_DEV_IO_TRACE 37 unsigned int btrace_seq; 38 #endif 39 40 unsigned int policy; 41 cpumask_t cpus_allowed; 42 43 #ifdef CONFIG_TREE_PREEMPT_RCU 44 int rcu_read_lock_nesting; 45 char rcu_read_unlock_special; 46 struct rcu_node *rcu_blocked_node; 47 struct list_head rcu_node_entry; 48 #endif /* #ifdef CONFIG_TREE_PREEMPT_RCU */ 49 50 #if defined(CONFIG_SCHEDSTATS) || defined(CONFIG_TASK_DELAY_ACCT) 51 struct sched_info sched_info; 52 #endif 53 54 struct list_head tasks; 55 struct plist_node pushable_tasks; 56 57 struct mm_struct *mm, *active_mm; 58 59 /* task state */ 60 int exit_state; 61 int exit_code, exit_signal; 62 int pdeath_signal; /* The signal sent when the parent dies */ 63 unsigned int personality; 64 unsigned did_exec:1; 65 unsigned in_execve:1; /* Tell the LSMs that the process is doing an 66 * execve */ 67 unsigned in_iowait:1; 68 69 70 /* Revert to default priority/policy when forking */ 71 unsigned sched_reset_on_fork:1; 72 73 pid_t pid; 74 pid_t tgid; 75 76 #ifdef CONFIG_CC_STACKPROTECTOR 77 /* Canary value for the -fstack-protector gcc feature */ 78 unsigned long stack_canary; 79 #endif 80 81 /* 82 * pointers to (original) parent process, youngest child, younger sibling, 83 * older sibling, respectively. (p->father can be replaced with 84 * p->real_parent->pid) 85 */ 86 struct task_struct *real_parent; /* real parent process */ 87 struct task_struct *parent; /* recipient of SIGCHLD, wait4() reports */ 88 /* 89 * children/sibling forms the list of my natural children 90 */ 91 struct list_head children; /* list of my children */ 92 struct list_head sibling; /* linkage in my parent's children list */ 93 struct task_struct *group_leader; /* threadgroup leader */ 94 95 /* 96 * ptraced is the list of tasks this task is using ptrace on. 97 * This includes both natural children and PTRACE_ATTACH targets. 98 * p->ptrace_entry is p's link on the p->parent->ptraced list. 99 */ 100 struct list_head ptraced; 101 struct list_head ptrace_entry; 102 103 /* 104 * This is the tracer handle for the ptrace BTS extension. 105 * This field actually belongs to the ptracer task. 106 */ 107 struct bts_context *bts; 108 109 /* PID/PID hash table linkage. */ 110 struct pid_link pids[PIDTYPE_MAX]; 111 struct list_head thread_group; 112 113 struct completion *vfork_done; /* for vfork() */ 114 int __user *set_child_tid; /* CLONE_CHILD_SETTID */ 115 int __user *clear_child_tid; /* CLONE_CHILD_CLEARTID */ 116 117 cputime_t utime, stime, utimescaled, stimescaled; 118 cputime_t gtime; 119 cputime_t prev_utime, prev_stime; 120 unsigned long nvcsw, nivcsw; /* context switch counts */ 121 struct timespec start_time; /* monotonic time */ 122 struct timespec real_start_time; /* boot based time */ 123 /* mm fault and swap info: this can arguably be seen as either mm-specific or thread-specific */ 124 unsigned long min_flt, maj_flt; 125 126 struct task_cputime cputime_expires; 127 struct list_head cpu_timers[3]; 128 129 /* process credentials */ 130 const struct cred *real_cred; /* objective and real subjective task 131 * credentials (COW) */ 132 const struct cred *cred; /* effective (overridable) subjective task 133 * credentials (COW) */ 134 struct mutex cred_guard_mutex; /* guard against foreign influences on 135 * credential calculations 136 * (notably. ptrace) */ 137 struct cred *replacement_session_keyring; /* for KEYCTL_SESSION_TO_PARENT */ 138 139 char comm[TASK_COMM_LEN]; /* executable name excluding path 140 - access with [gs]et_task_comm (which lock 141 it with task_lock()) 142 - initialized normally by flush_old_exec */ 143 /* file system info */ 144 int link_count, total_link_count; 145 #ifdef CONFIG_SYSVIPC 146 /* ipc stuff */ 147 struct sysv_sem sysvsem; 148 #endif 149 #ifdef CONFIG_DETECT_HUNG_TASK 150 /* hung task detection */ 151 unsigned long last_switch_count; 152 #endif 153 /* CPU-specific state of this task */ 154 struct thread_struct thread; 155 /* filesystem information */ 156 struct fs_struct *fs; 157 /* open file information */ 158 struct files_struct *files; 159 /* namespaces */ 160 struct nsproxy *nsproxy; 161 /* signal handlers */ 162 struct signal_struct *signal; 163 struct sighand_struct *sighand; 164 165 sigset_t blocked, real_blocked; 166 sigset_t saved_sigmask; /* restored if set_restore_sigmask() was used */ 167 struct sigpending pending; 168 169 unsigned long sas_ss_sp; 170 size_t sas_ss_size; 171 int (*notifier)(void *priv); 172 void *notifier_data; 173 sigset_t *notifier_mask; 174 struct audit_context *audit_context; 175 #ifdef CONFIG_AUDITSYSCALL 176 uid_t loginuid; 177 unsigned int sessionid; 178 #endif 179 seccomp_t seccomp; 180 181 /* Thread group tracking */ 182 u32 parent_exec_id; 183 u32 self_exec_id; 184 /* Protection of (de-)allocation: mm, files, fs, tty, keyrings, mems_allowed, 185 * mempolicy */ 186 spinlock_t alloc_lock; 187 188 #ifdef CONFIG_GENERIC_HARDIRQS 189 /* IRQ handler threads */ 190 struct irqaction *irqaction; 191 #endif 192 193 /* Protection of the PI data structures: */ 194 spinlock_t pi_lock; 195 196 #ifdef CONFIG_RT_MUTEXES 197 /* PI waiters blocked on a rt_mutex held by this task */ 198 struct plist_head pi_waiters; 199 /* Deadlock detection and priority inheritance handling */ 200 struct rt_mutex_waiter *pi_blocked_on; 201 #endif 202 203 #ifdef CONFIG_DEBUG_MUTEXES 204 /* mutex deadlock detection */ 205 struct mutex_waiter *blocked_on; 206 #endif 207 #ifdef CONFIG_TRACE_IRQFLAGS 208 unsigned int irq_events; 209 int hardirqs_enabled; 210 unsigned long hardirq_enable_ip; 211 unsigned int hardirq_enable_event; 212 unsigned long hardirq_disable_ip; 213 unsigned int hardirq_disable_event; 214 int softirqs_enabled; 215 unsigned long softirq_disable_ip; 216 unsigned int softirq_disable_event; 217 unsigned long softirq_enable_ip; 218 unsigned int softirq_enable_event; 219 int hardirq_context; 220 int softirq_context; 221 #endif 222 #ifdef CONFIG_LOCKDEP 223 # define MAX_LOCK_DEPTH 48UL 224 u64 curr_chain_key; 225 int lockdep_depth; 226 unsigned int lockdep_recursion; 227 struct held_lock held_locks[MAX_LOCK_DEPTH]; 228 gfp_t lockdep_reclaim_gfp; 229 #endif 230 231 /* journalling filesystem info */ 232 void *journal_info; 233 234 /* stacked block device info */ 235 struct bio *bio_list, **bio_tail; 236 237 /* VM state */ 238 struct reclaim_state *reclaim_state; 239 240 struct backing_dev_info *backing_dev_info; 241 242 struct io_context *io_context; 243 244 unsigned long ptrace_message; 245 siginfo_t *last_siginfo; /* For ptrace use. */ 246 struct task_io_accounting ioac; 247 #if defined(CONFIG_TASK_XACCT) 248 u64 acct_rss_mem1; /* accumulated rss usage */ 249 u64 acct_vm_mem1; /* accumulated virtual memory usage */ 250 cputime_t acct_timexpd; /* stime + utime since last update */ 251 #endif 252 #ifdef CONFIG_CPUSETS 253 nodemask_t mems_allowed; /* Protected by alloc_lock */ 254 int cpuset_mem_spread_rotor; 255 #endif 256 #ifdef CONFIG_CGROUPS 257 /* Control Group info protected by css_set_lock */ 258 struct css_set *cgroups; 259 /* cg_list protected by css_set_lock and tsk->alloc_lock */ 260 struct list_head cg_list; 261 #endif 262 #ifdef CONFIG_FUTEX 263 struct robust_list_head __user *robust_list; 264 #ifdef CONFIG_COMPAT 265 struct compat_robust_list_head __user *compat_robust_list; 266 #endif 267 struct list_head pi_state_list; 268 struct futex_pi_state *pi_state_cache; 269 #endif 270 #ifdef CONFIG_PERF_EVENTS 271 struct perf_event_context *perf_event_ctxp; 272 struct mutex perf_event_mutex; 273 struct list_head perf_event_list; 274 #endif 275 #ifdef CONFIG_NUMA 276 struct mempolicy *mempolicy; /* Protected by alloc_lock */ 277 short il_next; 278 #endif 279 atomic_t fs_excl; /* holding fs exclusive resources */ 280 struct rcu_head rcu; 281 282 /* 283 * cache last used pipe for splice 284 */ 285 struct pipe_inode_info *splice_pipe; 286 #ifdef CONFIG_TASK_DELAY_ACCT 287 struct task_delay_info *delays; 288 #endif 289 #ifdef CONFIG_FAULT_INJECTION 290 int make_it_fail; 291 #endif 292 struct prop_local_single dirties; 293 #ifdef CONFIG_LATENCYTOP 294 int latency_record_count; 295 struct latency_record latency_record[LT_SAVECOUNT]; 296 #endif 297 /* 298 * time slack values; these are used to round up poll() and 299 * select() etc timeout values. These are in nanoseconds. 300 */ 301 unsigned long timer_slack_ns; 302 unsigned long default_timer_slack_ns; 303 304 struct list_head *scm_work_list; 305 #ifdef CONFIG_FUNCTION_GRAPH_TRACER 306 /* Index of current stored adress in ret_stack */ 307 int curr_ret_stack; 308 /* Stack of return addresses for return function tracing */ 309 struct ftrace_ret_stack *ret_stack; 310 /* time stamp for last schedule */ 311 unsigned long long ftrace_timestamp; 312 /* 313 * Number of functions that haven't been traced 314 * because of depth overrun. 315 */ 316 atomic_t trace_overrun; 317 /* Pause for the tracing */ 318 atomic_t tracing_graph_pause; 319 #endif 320 #ifdef CONFIG_TRACING 321 /* state flags for use by tracers */ 322 unsigned long trace; 323 /* bitmask of trace recursion */ 324 unsigned long trace_recursion; 325 #endif /* CONFIG_TRACING */ 326 unsigned long stack_start; 327 };
解析task_struct结构体
(1)进程的标识 PID(process identifier):
pid_t pid;//进程的唯一标识
pid_t tgid;// 线程组的领头线程的pid成员的值
32位无符号整型数据。但最大值取32767。表示每一个进程的标识符。也是内核提供给用户程序的借口,用户程序通过pid操作程序。因为Unix的原因引入还引入了线程组的概念。称为:tgid。一个线程组中的所有线程使用和该线程组中的第一个轻量级线程的pid,被存在tgid成员中。当进程没有线程时,tgid=pid;当有多线程时,tgid表示的是主线程的id,而pid表示每一个线程自己的id。
(2)进程的状态 volatile long state
state的可能取值是:
#define TASK_RUNNING 0//进程要么正在执行,要么准备执行
#define TASK_INTERRUPTIBLE 1 //可中断的睡眠,可以通过一个信号唤醒
#define TASK_UNINTERRUPTIBLE 2 //不可中断睡眠,不可以通过信号进行唤醒
#define __TASK_STOPPED 4 //进程停止执行
#define __TASK_TRACED 8 //进程被追踪
/* in tsk->exit_state */
#define EXIT_ZOMBIE 16 //僵尸状态的进程,表示进程被终止,但是父进程还没有获取它的终止信息,比如进程有没有执行完等信息。
#define EXIT_DEAD 32 //进程的最终状态,进程死亡
/* in tsk->state again */
#define TASK_DEAD 64 //死亡
#define TASK_WAKEKILL 128 //唤醒并杀死的进程
#define TASK_WAKING 256 //唤醒进程
(3)进程的优先级 long priority
Priority的值给出进程每次获取CPU后可使用的时间(按jiffies计)。优先级可通过系统sys_setpriorty改变(在kernel/sys.c中)。
程序计数器:程序中即将被执行的下一条指令的地址。
内存指针:包括程序代码和进程相关数据的指针,还有和其他进程共享的内存块的指针。
上下文数据:进程执行时处理器的寄存器中的数据。
I/O状态信息:包括显示的I/O请求,分配给进程的I/O设备(如磁带驱动器)和被进程使用的文件列表。
审计信息:可包括处理器时间总和,使用的时钟数总和,时间限制,审计号等。
(4)进程调度信息
表示当前进程或一个进程允许运行的时间,待到该进程的时间片运行结束,CPU会从运行队列上拿出另一个进程运行。
need_resched:调度标志
Nice:静态优先级
Counter:动态优先级;重新调度进程时会在run_queue中选出Counter值最大的进程。也代表该进程的时间片,运行中不断减少。
Policy:调度策略开始运行时被赋予的值
rt_priority:实时优先级
(5)进程通信有关信息(IPC:Inter_Process Communication)
unsigned long signal:进程接收到的信号。每位表示一种信号,共32种。置位有效。
unsigned long blocked:进程所能接受信号的位掩码。置位表示屏蔽,复位表示不屏蔽。
Spinlock_t sigmask_lock:信号掩码的自旋锁
Long blocked:信号掩码
Struct sem_undo *semundo:为避免死锁而在信号量上设置的取消操作
Struct sem_queue *semsleeping:与信号量操作相关的等待队列
struct signal_struct *sig:信号处理函数
(6)进程信息
Linux中存在多进程,而多进程中进程之间的关系可能是父子关系,兄弟关系。
除了祖先进程外,其他进程都有一个父进程,通过folk创建出子进程来执行程序。除了表示各自的pid外,子进程的绝大多数信息都是拷贝父进程的信息。且父进程对子进程手握生杀大权,即子进程时是父进程创建出来的,而父进程也可以发送命令杀死子进程。
(7)时间信息
Start_time:进程创建时间
Per_cpu_utime:进程在执行时在用户态上耗费的时间。
Pre_cpu_stime:进程在执行时在系统态上耗费的时间。
ITIMER_REAL:实时定时器,不论进程是否运行,都在实时更新。
ITIMER_VIRTUAL:虚拟定时器,只有进程运行在用户态时才会更新。
ITIMER_PROF:概况定时器,进程在运行处于用户态和系统态时更新。
(8)文件信息
文件的打开和关闭都是资源的一种操作,Linux中的task_struct中有两个结构体储存这两个信息。
Sruct fs_struct *fs:进程的可执行映象所在的文件系统,有两个索引点,称为root和pwd,分别指向对应的根目录和当前目录。
Struct files_struct *files:进程打开的文件
(8)地址空间/虚拟内存信息
每个进程都有自己的一块虚拟内存空间,用mm_struct来表示,mm_struct中使用两个指针表示一段虚拟地址空间,然后在最终时通过页表映射到真正的物理内存上。
(9)页面管理信息
Int swappable:进程占用的内存页面是否可换出。
Unsigned long min_flat,maj_flt,nswap:进程累计换出、换入页面数。
Unsigned long cmin_flat,cmaj_flt,cnswap:本进程作为祖先进程,其所有层次子进程的累计换出、换入页面数。
(10)对称对处理机信息
Int has_cpu: 进程是否当前拥有CPU
Int processor: 进程当前正在使用的CPU
Int lock_depth: 上下文切换时内核锁的深度
(11)上下文信息:
struct desc_struct *ldt:进程关于CPU段式存储管理的局部描述符表的指针。
struct thread_struct tss:任务状态段。与Intel的TSS进行互动,当前运行的TSS保存在PCB的tss中,新选中的的进程的tss保存在TSS。
(12)信号量数据成员
struct sem_undo *semundo:进程每一次操作一次信号量,都会生成一个undo操作。保存在sem_undo结构体中,最终在进程异常终止结束的时候,sem_undo的成员semadj就会指向一个数组,这个数组中每个成员都表示之前每次undo的量。
truct sem_queue *semsleeping:进程在操作信号量造成堵塞时,进程会被送入semsleeping指示的关于该信号量的sem_queue队列。
(13)进程队列指针
struct task_struct *next_task,*prev_task:所有进程均有各自的PCB。且各个PCB会串在一起,形成一个双向链表。其next_task和prev_task就表示上一个或下一个PCB,即前后指针。进程链表的头和尾都是0号进程。
struct task_struct *next_run,*prev_run:由进程的run_queue中产生作用的,指向上一个或下一个可运行的进程,链表的头和尾都是0号进程。
struct task_struct *p_opptr:原始父进程(祖先进程)
struct task_struct *p_pptr :父进程
struct task_struct *p_cptr:子进程
struct task_struct *p_ysptr:弟进程
struct task_struct *p_osptr:兄进程
以上分别是指向原始父进程(original parent)、父进程(parent)、子进程(youngest child)及新老兄弟进程(younger sibling,older sibling)的指针。
current:当前正在运行进程的指针。
struct task_struct init_task:0号进程的PCB,进程的跟=根,始终是INIT_TASK。
char comm[16]:进程正在执行的可执行文件的文件名。
int errno:进程最后一次出错的错误号。0表示无错误。