Linux内核进程管理子系统有什么第十回 —— 进程主结构详解(6)

接前一篇文章:Linux内核进程管理子系统有什么第九回 —— 进程主结构详解(5)

 

本文内容参考:

Linux内核进程管理专题报告_linux rseq-优快云博客

《趣谈Linux操作系统 核心原理篇:第三部分 进程管理》—— 刘超

《图解Linux内核 基于6.x》 —— 姜亚华 机械工业出版社

Linux——一文彻底了解进程id和线程id的关系(什么是pid、tgid、lwp、pthread_t)-优快云博客

特此致谢!

 

进程管理核心结构 —— task_struct

1. 任务ID相关成员

    pid_t				pid;
	pid_t				tgid;
 
	struct task_struct		*group_leader;
 
    struct list_head		thread_group;

前几回围绕进程id(PID)、父进程id(PPID)、进程组id(PGID)、会话id(SID)、线程id(LWP)、线程组的线程数(NLWP),结合例程进行了深入解析。

回归到之前的问题:既然是唯一标识的ID,那么有一个不就可以了,怎么上边有个pid_t pid,还有个pid_t tgid?弄俩干什么?

经过之前的讲解,现在应该清楚了,之所以这样做,是因为在Linux内核中,无论是进程还是线程,都统一称为(当作)任务,都由一个统一的struct task_struct管理。那么到底当前这个任务是一个进程还是一个线程,就得区分开来。

成员pid_t pid代表进程id(process id);成员tgid是线程组id(thread group id)。

任何一个进程,如果只有主线程,则pid是它自己,tid也是它自己,group_leader指向的还是它自己。就像示例代码中的父进程。

也就是说,对于父进程来说,struct task_struct中的pid对应的是它自己的LWP,而tgid对应它自己的PID。LWP和PID两者相等。

如果一个进程创建了其它线程(非主线程),那么就不一样了。每个线程有自己的pid,对应的就是LWP;tgid就是进程的主线程的PID,对应的就是子进程的PID;group_leader指向的就是进程的主线程。

也就是说,对于子进程来说,struct task_struct中的pid对应的是它自己的LWP,而tgid对应它自己的PID。只不过LWP和PID两者相等。

而对于子进程创建的两个线程来说,struct task_struct中的pid对应线程自己的LWP,而tgid对应子进程的PID。LWP和PID两者不同。

有了tgid,就能够区分某一struct task_struct代表的是一个进程还是一个线程了。pid和tgid相等的是进程,不相等的是线程。

以上的关系还是有些绕,说得更直白一些:struct task_struct中的成员pid_t pid虽然名字是process id,但其实代表的线程id、即task_struct的编号(对应ps命令返回结果中的LWP),每个task_struct各不相同;成员tgid名字thread group id,其实也就是进程的id(对应ps命令返回结果中的PID),同一个进程里每一个线程的task_struct中tgid值都一样。是这样一个“交叉”关系:

再结合实际结果看一下:

子进程:

子进程创建的线程1

终于讲清楚了的struct task_struct的成员pid_t pid和pid_t tgid。

​    pid_t				pid;
	pid_t				tgid;
 
	struct task_struct		*group_leader;
 
    struct list_head		thread_group;

上边在讲成员group_leader的时候曾讲到:

有人可能又有疑问了:tgid和group_leader都是进程的主线程,那这两个参数不就重复了么?

需要注意:tgid的类型是pid_t,而group_leader的类型是struct task_struct *,一个是id,一个是指针。知道id,才能找到对应的具体是哪一个task_struct实例。

最后,同一个线程组的线程,它们的task_struct都通过struct list_head thread_group成员连接到同一链表中。链表的头为线程组领导进程的struct task_struct的struct list_head thread_group字段。如下图所示:

最后的最后,对于ps -eLo命令返回的结果中有一点再特别说明和强调一下:

子进程和其创建的两个线程的PID都是一个,是子进程的PID;但这三者的PGID与父进程的PGID相同,都是父进程的PID。也就是说,父进程(主进程)与子进程和其创建的两个线程共属于同一个进程组,父进程是组长。

至此,struct task_struct中任务ID相关成员就讲解完了。更多成员的解析请看下回。

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

蓝天居士

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值