• 调研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表示无错误。

  • 相关阅读:
    Android的selector,背景选择器
    JAVA静态和非静态内部类
    Android应用资源--之属性(Attribute)资源
    contentprovider的学习实例总结
    转:Android 2.3 代码混淆proguard技术介绍
    忘掉旋转,利用2-3-4树,学习红黑树
    ios 定位获取当前位置信息
    地图相关
    mac下,svn配置
    NimBus一个好的开发框架
  • 原文地址:https://www.cnblogs.com/cuckoo-/p/10966158.html
Copyright © 2020-2023  润新知