進程的描述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表示無錯誤。