《深入理解Linux内核》--第三章 进程:读书笔记

本文深入探讨了进程管理的核心概念,包括进程与线程的区别、轻量级进程的应用场景、进程间的关系及其生命周期管理。此外,还详细介绍了进程切换的具体步骤和技术细节。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

   最大体会关注的是进程的权限、父进程子进程的关系、进程与线程的关系 以及 进程线程的生命周期。
一、进程、轻量级进程,线程
     进程拥有自己独立空间。
     轻量级进程:两个轻量级进程基本上可以共享一些资源,诸如地址空间、打开的文件等。(之所以说轻量级,就是说偏向线程,可以共享一些资源,但是又不是完全的线程。)
     线程,内核看做是简单的进程。
     为什么要轻量级进程而非线程,例子:象棋程序的控制图像化棋盘部分、思考下一步移动的思考部分。两部分如果都是进程则不能共享数据(进程间共享数据困难,当然也可以通过各种方式做到);如果都是线程,则一个在运行,另一个则阻塞(同一进程内的多线程之间阻塞);运用轻量级进程可以保证 共享部分数据 和 运行 兼顾。

     1)进程描述符 中thread_info,

未命名6 
    运用联合结构表示了一个进程的线程描述符和内核栈:
    union thread_union{
          struct thread_info thread_info;
          unsigned long stack[2048]; /*对4k的栈数组下表是1024 ,long是4byte */
    }
  thread_info 从低地址向高处增长,堆栈stack从高地址往低地址增长,esp指向当前栈顶。
  2)双向链表结构
   list_head数据结构是双向链表结构,next,prev指针。
  遍历进程链表的宏:
  #define for_each_process(p)/
        for(p=&init_task;(p=list_entry(p)->tasks.next,struct task_struct,tasks)!=&init_task;)
  3)pidhash表及链表
   散列表强调的是空间而不是在固定的时间内找到表中的最后一个元素。(当然hash能够很快找到对应的元素)
   #define pid_hashfn(x) hash_long((unsigned long) x,pidhash_shift);
  这里的pidhash_shift 值一般取11。
   unsigned long hash_long(unsigned long val, unsigned int bits)
   {
        unsigned long hash=val *0x9e370001UL;
        return hash>>(32-bits);
   }
    0x9e370001=2 654 404 609=2^31+2^29-2^25+2^22-2^19-2^16+1.
    是接近黄金比例的2^32的一个素数。(也称为 “魔数常量”)
   未命名6
二、进程间的关系
   real_parent,指向创建了P进程的描述符,若不存在,则指向init(1)进程
   parent        ,指向P的当期父进程(与real_parent 不同发生在,监控P时ptrace()系统调用)
   children
   sibling,     指向兄弟进程,(注意的是sibling.prev或sibling.next 可能指向parent)

三、进程生命周期
     1)创建进程,有三种方式可以创建:
              (1)写时复制技术允许父子进程读相同的物理页。只要两者之一试图写一个物理页,内核就将
                                     把这个页的内容拷贝到一个新的物理页,并把新的物理页分配给正在写的进程
             (2)轻量级级进程:允许父子进程共享每进程(per-process)在内核的很多数据结构。
             (3)vfork(),阻塞父进程的执行,直到子进程退出或执行一个新的其他程序。
         注意的三个系统调用:clone()、fork()、vfork()
     2)撤销进程(由自己撤销)
          exit_group();线程组
          exit();
     3)进程删除(由父进程删除)
         父进程wait()哪些僵死进程,如果wait()成功则删除子进程。如果父进程先结束,则会有很多僵死进程,这些孤儿进程会将父进程指向init(),init()负责wait()操作。

 

进程切换:1)切换页全局目录以安装一个新的地址空间;
               2)切换内核态堆栈 和 硬件上下文,因为硬件上下文 提供了内核执行新进程所需要的所有信
                    息。这一步由 switch_to 宏执行。

四、其它

TSS(Task State Segment)
TSSD(Task State Segment Descriptor)


FPU、MMX和XMM寄存器的加载使用需要另外程序操作
union i387_unio{
    struct i387_fsave_struct fsave;
    struct i387_fxsave_struct fxsave;
    struct i387_soft_struct soft;
};

内核线程 只运行在内核态,只使用大于PAGE_OFFSET(3G)的线性地址空间。其他普通进程在用户态或内核态都可以访问4G的线性地址空间。

进程0 (idle进程 或 swapper进程),是Linux在初始化阶段从无到有创建的一个内核线程。(祖先)
进程1 (init进程,在整个系统运行中一直存活),内核初始化后由内核线程 变为 普通进程,拥有
           per-process内核数据结构,创建和监控在操作系统外层执行的所有进程的活动。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值