调研task_struct结构体

进程的描述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表示无错误。

猜你喜欢

转载自www.cnblogs.com/cuckoo-/p/10966158.html