Linux中task_struct结构体分析

所在文件

task_struct结构体位于内核文件/include/linux/sched.h中。

分析

去GitHub上查看源码中的该结构体,分析如下:

struct task_struct {
    
    
	/*
	 * 进程状态。
	 */
	volatile long state;	/* -1 unrunnable, 0 runnable, >0 stopped */
	/*
	 * 进程的基本信息。
	 */
	struct thread_info *thread_info;
	atomic_t usage;
	unsigned long flags;	/* per process flags, defined below */
	unsigned long ptrace;

	int lock_depth;		/* Lock depth */

	/*
	 * 进行的动态优先权和静态优先权
	 */
	int prio, static_prio;
	/*
	 * 进程所在运行队列。每个优先级对应一个运行队列。
	 */
	struct list_head run_list;
	/*
	 * 指向当前运行队列的prio_array_t
	 */
	prio_array_t *array;

	/*
	 * 进程的平均睡眠时间
	 */
	unsigned long sleep_avg;
	/*
	 * timestamp:进程最近插入运行队列的时间。或涉及本进程的最近一次进程切换的时间
	 * last_ran:最近一次替换本进程的进程切换时间。
	 */
	unsigned long long timestamp, last_ran;
	/*
	 * 进程被唤醒时所使用的代码。
	 * 0:进程处于TASK_RUNNING状态。
	 * 1:进程处于TASK_INTERRUPTIBLE或者TASK_STOPPED状态,而且正在被系统调用服务例程或内核线程唤醒。
	 * 2:进程处于TASK_INTERRUPTIBLE或者TASK_STOPPED状态,而且正在被ISR或者可延迟函数唤醒。
	 * -1:表示从UNINTERRUPTIBLE状态被唤醒
	 */
	int activated;

	/*
	 * 进程的调度类型:sched_normal,sched_rr或者sched_fifo
	 */
	unsigned long policy;
	/*
	 * 能执行进程的CPU的位掩码
	 */
	cpumask_t cpus_allowed;
	/*
	 * time_slice:在进程的时间片中,还剩余的时钟节拍数。
	 * first_time_slice:如果进程肯定不会用完其时间片,就把该标志设置为1。
	 *
	 * Dagger-axe注:目的为加速子进程的返回,防止内存中进程过多。
	 */
	unsigned int time_slice, first_time_slice;

#ifdef CONFIG_SCHEDSTATS
	struct sched_info sched_info;
#endif

	/*
	 * 通过此链表把所有进程链接到一个双向链表中。
	 */
	struct list_head tasks;
	/*
	 * ptrace_list/ptrace_children forms the list of my children
	 * that were stolen by a ptracer.
	 */
	/*
	 * 链表的头。该链表包含所有被debugger程序跟踪的P的子进程。
	 */
	struct list_head ptrace_children;
	/*
	 * 指向所跟踪进程的实际父进程链表的前一个下一个元素。
	 */
	struct list_head ptrace_list;

	/*
	 * mm:指向内存区描述符的指针
	 */
	struct mm_struct *mm, *active_mm;

/* task state */
	struct linux_binfmt *binfmt;
	long exit_state;
	int exit_code, exit_signal;
	int pdeath_signal;  /*  The signal sent when the parent dies  */
	unsigned long personality;
	/*
	 * 进程发出execve系统调用的次数。
	 */
	unsigned did_exec:1;
	/*
	 * 进程PID
	 */
	pid_t pid;
	/*
	 * 线程组领头线程的PID。
	 */
	pid_t tgid;
	/* 
	 * pointers to (original) parent process, youngest child, younger sibling,
	 * older sibling, respectively.  (p->father can be replaced with 
	 * p->parent->pid)
	 */
	/*
	 * 指向创建进程的进程的描述符。
	 * 如果进程的父进程不再存在,就指向进程1的描述符。
	 * 因此,如果用户运行一个后台进程而且退出了shell,后台进程就会成为init的子进程。
	 */
	struct task_struct *real_parent; /* real parent process (when being debugged) */
	/*
	 * 指向进程的当前父进程。这种进程的子进程终止时,必须向父进程发信号。
	 * 它的值通常与real_parent一致。
	 * 但偶尔也可以不同。例如:当另一个进程发出监控进程的ptrace系统调用请求时。
	 */
	struct task_struct *parent;	/* parent process */
	/*
	 * children/sibling forms the list of my children plus the
	 * tasks I'm ptracing.
	 */
	/*
	 * 链表头部。链表指向的所有元素都是进程创建的子进程。
	 */
	struct list_head children;	/* list of my children */
	/*
	 * 指向兄弟进程链表的下一个元素或前一个元素的指针。
	 */
	struct list_head sibling;	/* linkage in my parent's children list */
	/*
	 * P所在进程组的领头进程的描述符指针。
	 */
	struct task_struct *group_leader;	/* threadgroup leader */

	/* PID/PID hash table linkage. */
	/*
	 * PID散列表。通过这四个表,可以方便的查找同一线程组的其他线程,同一会话的其他进程等等。
	 */
	struct pid pids[PIDTYPE_MAX];

	struct completion *vfork_done;		/* for vfork() */
	/*
	 * 子进程在用户态的地址。这些用户态地址的值将被设置或者清除。
	 * 在do_fork时记录这些地址,稍后再设置或者清除它们的值。
	 */
	int __user *set_child_tid;		/* CLONE_CHILD_SETTID */
	int __user *clear_child_tid;		/* CLONE_CHILD_CLEARTID */

	/*
	 * 进程的实时优先级。
	 */
	unsigned long rt_priority;
	/*
	 * 以下三对值用于用户态的定时器。当定时器到期时,会向用户态进程发送信号。
	 * 每一对值分别存放了两个信号之间以节拍为单位的间隔,及定时器的当前值。
	 */
	unsigned long it_real_value, it_real_incr;
	cputime_t it_virt_value, it_virt_incr;
	cputime_t it_prof_value, it_prof_incr;
	/*
	 * 每个进程的动态定时器。用于实现ITIMER_REAL类型的间隔定时器。
	 * 由settimer系统调用初始化。
	 */
	struct timer_list real_timer;
	/*
	 * 进程在用户态和内核态下经过的节拍数
	 */
	cputime_t utime, stime;
	unsigned long nvcsw, nivcsw; /* context switch counts */
	struct timespec start_time;
/* mm fault and swap info: this can arguably be seen as either mm-specific or thread-specific */
	unsigned long min_flt, maj_flt;
/* process credentials */
	uid_t uid,euid,suid,fsuid;
	gid_t gid,egid,sgid,fsgid;
	struct group_info *group_info;
	kernel_cap_t   cap_effective, cap_inheritable, cap_permitted;
	unsigned keep_capabilities:1;
	struct user_struct *user;
#ifdef CONFIG_KEYS
	struct key *session_keyring;	/* keyring inherited over fork */
	struct key *process_keyring;	/* keyring private to this process (CLONE_THREAD) */
	struct key *thread_keyring;	/* keyring private to this thread */
#endif
	int oomkilladj; /* OOM kill score adjustment (bit shift). */
	char comm[TASK_COMM_LEN];
/* file system info */
	/*
	 * 文件系统在查找路径时使用,避免符号链接查找深度过深,导致死循环。
	 * link_count是__do_follow_link递归调用的层次。
	 * total_link_count调用__do_follow_link的总次数。
	 */
	int link_count, total_link_count;
/* ipc stuff */
	struct sysv_sem sysvsem;
/* CPU-specific state of this task */
	struct thread_struct thread;
/* filesystem information */
	/*
	 * 与文件系统相关的信息。如当前目录。
	 */
	struct fs_struct *fs;
/* open file information */
	/*
	 * 指向文件描述符的指针
	 */
	struct files_struct *files;
/* namespace */
	struct namespace *namespace;
/* signal handlers */
	/*
	 * 指向进程的信号描述符的指针
	 */
	struct signal_struct *signal;
	/*
	 * 指向进程的信号处理程序描述符的指针
	 */
	struct sighand_struct *sighand;

	/*
	 * blocked:被阻塞的信号的掩码
	 * real_blocked:被阻塞信号的临时掩码(由rt_sigtimedwait系统调用使用)
	 */
	sigset_t blocked, real_blocked;
	/*
	 * 存放私有挂起信号的数据结构
	 */
	struct sigpending pending;

	/*
	 * 信号处理程序备用堆栈的地址
	 */
	unsigned long sas_ss_sp;
	/*
	 * 信号处理程序备用堆栈的大小
	 */
	size_t sas_ss_size;
	/*
	 * 指向一个函数的指针,设备驱动程序使用这个函数阻塞进程的某些信号
	 */
	int (*notifier)(void *priv);
	/*
	 * 指向notifier函数可能使用的数据
	 */
	void *notifier_data;
	sigset_t *notifier_mask;
	
	void *security;
	struct audit_context *audit_context;

/* Thread group tracking */
   	u32 parent_exec_id;
   	u32 self_exec_id;
/* Protection of (de-)allocation: mm, files, fs, tty, keyrings */
	spinlock_t alloc_lock;
/* Protection of proc_dentry: nesting proc_lock, dcache_lock, write_lock_irq(&tasklist_lock); */
	spinlock_t proc_lock;
/* context-switch lock */
	spinlock_t switch_lock;

/* journalling filesystem info */
	/*
	 * 当前活动日志操作处理的地址。
	 * 正在使用的原子操作对象。
	 */
	void *journal_info;

/* VM state */
	struct reclaim_state *reclaim_state;

	struct dentry *proc_dentry;
	struct backing_dev_info *backing_dev_info;

	struct io_context *io_context;

	unsigned long ptrace_message;
	siginfo_t *last_siginfo; /* For ptrace use.  */
/*
 * current io wait handle: wait queue entry to use for io waits
 * If this thread is processing aio, this points at the waitqueue
 * inside the currently handled kiocb. It may be NULL (i.e. default
 * to a stack based synchronous wait) if its doing sync IO.
 */
	wait_queue_t *io_wait;
/* i/o counters(bytes read/written, #syscalls */
	u64 rchar, wchar, syscr, syscw;
#if defined(CONFIG_BSD_PROCESS_ACCT)
	u64 acct_rss_mem1;	/* accumulated rss usage */
	u64 acct_vm_mem1;	/* accumulated virtual memory usage */
	clock_t acct_stimexpd;	/* clock_t-converted stime since last update */
#endif
#ifdef CONFIG_NUMA
  	struct mempolicy *mempolicy;
	short il_next;
#endif
};

参考资料

https://github.com/jasonactions/linux2.6.11_comment/blob/master/include/linux/sched.h

猜你喜欢

转载自blog.csdn.net/m0_46161993/article/details/109561975
今日推荐