task_stuct

task_struct是进程描述符。操作系统通过task_struct感知进程的存在。我学习内核的入口点就是该结构体。
现在就分析分析该结构体吧。
该结构体在内核中的位置:./include/Linux/sched.h 

structtask_struct { 

      volatile long state; 
        
这个字段来描述进程的状态。这儿有个关键词volatile可是
一个熟悉的陌生人。在学C的时候一直都见过,但不知道有什么作用,现在终于有个地方用到了。这个关键词是告诉编译器不要对其优化,编译器有一个缓存优化的习惯,比如说,第一次在内存取数,编译器发现后面还要用这个变量,于是把这个变量的值就放在寄存器中。这个关键词就是要求编译器不要优化,每次都让CPU去内存取数。以确保状态的变化能及时地反映上来。
    ---------------------------------------------------------------------------------------------------  

       struct list_headtasks;
   该字段用来把系统中的PCB通过双向循环链表链接起来。可以写了几种形式的内核模块来遍历这个链表。
     ----------------------------------------------------------------------------------------------------

     struct mm_struct *mm
  
这个字段比较重要,是进程的内存描述符。我在后面会有一个内核模块来打印进程的所有虚存区的起始和末尾地址。进程的虚存区有两组组织方式,一种是链表,一种是红黑树。我后面的程序用了链表的遍历和二叉树的先序方式遍历红黑树。
     ----------------------------------------------------------------------------------------------------

    int exit_code
   
当一个进程通过exit()结束进程后,会变成一个僵尸进程,
僵尸进程几乎释放了其他所有的资源,但PCB没有释放,其中PCB中的这个字段就是记录退出的退出码。
   -----------------------------------------------------------------------------------------------------

    pid_t pid; 
    pid_t tgid;
       进程的标识信息,pid表示进程IDtgid是便是线程组的ID,其实,我们调用getpid()这个系统调用的时候返回的是tgid
这样的目的是为了兼顾POSIX标准,为了兼顾POSIX标准,linux引入了线程组的概念。当进程中没有多线程时,这两个值一样,当有多个线程时,tgid记录主线程的id,pid记录各个线程自己独有的id,这样就可以保证进程中每个线程getpid()返回出来的值一样了。

在Linux系统中,一个线程组中的所有线程使用和该线程组的领头线程(该组中的第一个轻量级进程)相同的PID,并被存放在tgid成员中。只有线程组 的领头线程的pid成员才会被设置为与tgid相同的值。注意,getpid()系统调用返回的是当前进程的tgid值而不是pid值。   

 ------------------------------------------------------------------------------------------------------

         struct list_headthread_group;
        
这个字段我实验过,就是在用户态写一个多线程的程序,然后通过该字段遍历线程组中所有线程的PCB,这个字段将一个进程(也就是一个线程组)中的所有线程的PCB通过链表链接起来。
用户态的的线程组中有三个线程,结果如下:
[  803.985895] pid = 2151,tgid = 2151,name= a.out

[  803.985904] pid = 2152,tgid = 2151,name= a.out
[  803.985909] pid = 2153,tgid = 2151,name= a.out
由此可以看出getpid返回出的是tgid而不是pid
    --------------------------------------------------------------------------------------------------

        char comm[TASK_COMM_LEN]; 
          这个字段很简单,就是一个字符数组记录这个进程的名字。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值