Linux内核进程管理子系统有什么第十六回 —— 进程主结构详解(12)
接前一篇文章:Linux内核进程管理子系统有什么第十五回 —— 进程主结构详解(11)
本文内容参考:
Linux内核进程管理专题报告_linux rseq-CSDN博客
《趣谈Linux操作系统 核心原理篇:第三部分 进程管理》—— 刘超
《图解Linux内核 基于6.x》 —— 姜亚华 机械工业出版社
特此致谢!
进程管理核心结构 —— task_struct
2. 任务状态相关成员
上一回继续解析task_struct结构中任务状态相关的成员,包括以下字段:
unsigned int __state;int exit_state;unsigned int flags;
解析完了进程的退出状态int exit_state字段。本回解析unsigned int flags字段。
字段 | 类型 | 描述 |
---|---|---|
__state | unsigned int | 进程的状态 |
exit_state | int | 进程退出状态 |
flags | unsigned int | 进程的标记 |
(3)进程的标志
进程的状态与进程的运行、调度有关系。还有其它的一些状态,称之为进程的标志。进程的标志由struct task_struct中的unsigned int flags字段表示。这些标志都被定义为宏,以PF开头(PF是Process Flag的缩写)。定义在include/linux/sched.h中,如下:
/** Per process flags*/
#define PF_VCPU 0x00000001 /* I'm a virtual CPU */
#define PF_IDLE 0x00000002 /* I am an IDLE thread */
#define PF_EXITING 0x00000004 /* Getting shut down */
#define PF_POSTCOREDUMP 0x00000008 /* Coredumps should ignore this task */
#define PF_IO_WORKER 0x00000010 /* Task is an IO worker */
#define PF_WQ_WORKER 0x00000020 /* I'm a workqueue worker */
#define PF_FORKNOEXEC 0x00000040 /* Forked but didn't exec */
#define PF_MCE_PROCESS 0x00000080 /* Process policy on mce errors */
#define PF_SUPERPRIV 0x00000100 /* Used super-user privileges */
#define PF_DUMPCORE 0x00000200 /* Dumped core */
#define PF_SIGNALED 0x00000400 /* Killed by a signal */
#define PF_MEMALLOC 0x00000800 /* Allocating memory */
#define PF_NPROC_EXCEEDED 0x00001000 /* set_user() noticed that RLIMIT_NPROC was exceeded */
#define PF_USED_MATH 0x00002000 /* If unset the fpu must be initialized before use */
#define PF__HOLE__00004000 0x00004000
#define PF_NOFREEZE 0x00008000 /* This thread should not be frozen */
#define PF__HOLE__00010000 0x00010000
#define PF_KSWAPD 0x00020000 /* I am kswapd */
#define PF_MEMALLOC_NOFS 0x00040000 /* All allocation requests will inherit GFP_NOFS */
#define PF_MEMALLOC_NOIO 0x00080000 /* All allocation requests will inherit GFP_NOIO */
#define PF_LOCAL_THROTTLE 0x00100000 /* Throttle writes only against the bdi I write to,* I am cleaning dirty pages from some other bdi. */
#define PF_KTHREAD 0x00200000 /* I am a kernel thread */
#define PF_RANDOMIZE 0x00400000 /* Randomize virtual address space */
#define PF__HOLE__00800000 0x00800000
#define PF__HOLE__01000000 0x01000000
#define PF__HOLE__02000000 0x02000000
#define PF_NO_SETAFFINITY 0x04000000 /* Userland is not allowed to meddle with cpus_mask */
#define PF_MCE_EARLY 0x08000000 /* Early kill for mce process policy */
#define PF_MEMALLOC_PIN 0x10000000 /* Allocation context constrained to zones which allow long term pinning. */
#define PF__HOLE__20000000 0x20000000
#define PF__HOLE__40000000 0x40000000
#define PF_SUSPEND_TASK 0x80000000 /* This thread called freeze_processes() and should not be frozen */
常见的取值见下表:
标志 | 描述 |
---|---|
PF_IDLE | idle进程 |
PF_EXITING | 进程正在退出 |
PF_VCPU | 进程运行在虚拟CPU上 |
PF_WQ_WORKER | 进程是一个workqueue的worker |
PF_SUPERPRIV | 进程拥有超级用户权限 |
PF_SIGNALED | 进程被某个信号杀掉 |
PF_NOFREEZE | 进程不能被freeze |
PF_KTHREAD | 进程是一个内核线程 |
对于其中一些标志进行进一步说明:
- PF_EXITING
表示正在退出。当有这个flag的时候,在find_alive_thread函数中找活着的任务时,遇到这个flag的,就直接跳过。
- PF_VCPU
表示进程运行在虚拟CPU上。在account_system_time函数中,统计进程的系统运行时间,如果有这个flag,就调用account_guest_time函数,按照客户机的时间进行统计。
- PF_FORKNOEXEC
表示fork完了、还没有exec。在_do_fork函数中调用copy_process函数,这个时候把flag设置为PF_FORKNOEXEC。当exec中调用了load_elf_binary函数的时候,再将这个flag去掉。
至此,struct task_struct中任务状态相关成员就讲解完了。更多成员的解析请看下回。