20135302魏静静——linux课程第六周实验及总结

linux课程第六周实验及总结

实验及学习总结

1.进程描述符task_struct数据结构 

  • 进程的作用:

    将信号、进程间通信、内存管理和文件系统联系起来

  • 操作系统的三大功能:

    进程管理、内存管理、文件系统

  • 内核通过唯一的进程标识PID来区别每个进程

  • Linux为每个进程分配一个8KB大小的内存区域,用于存放该进程两个不同的数据结构:Thread_info和进程的内核堆栈
  • task_struct结构的大体框架:

  • 进程描述符中的state域描述了进程的当前状态:
    • task_running
    • task_interruprtion
    • task_uninterruption
    • task_traced
    • task_stopped

2.进程的创建

fork、vfork和clone三个系统调用都可以创建一个新进程,而且都是通过调用do_fork来实现进程的创建
1号进程是所有用户态进程的祖先,0号进程是所有内核线程的祖先
  • 进程的创建大致步骤:
    1. 调用dup_task_struct()为新进程分配内核栈,task_struct等,其中的内容与父进程相同。
    2. check新进程(进程数目是否超出上限等)
    3. 清理新进程的信息(比如PID置0等),使之与父进程区别开。
    4. 新进程状态置为 TASK_UNINTERRUPTIBLE
    5. 更新task_struct的flags成员。
    6. 调用alloc_pid()为新进程分配一个有效的PID
    7. 根据clone()的参数标志,拷贝或共享相应的信息
    8. 做一些扫尾工作并返回新进程指针
    • 从堆栈来看:
           
  •  那么上图中的schedule_tuil做了什么呢?我们可以从实验中看到:

       

  • 建一个新进程在内核中的执行过程
    • 复制一个PCB——task_struct,见copy_process内部
      • err = arch_dup_task_struct(tsk, orig);

    • 给新进程分配一个新的内核堆栈

      • ti = alloc_thread_info_node(tsk, node);

      • tsk->stack = ti;

      • setup_thread_stack(tsk, orig); //这里只是复制thread_info,而非复制内核堆栈

    • 从用户态的代码看fork():函数返回了两次,即在父子进程中各返回一次

      • *childregs = *current_pt_regs(); //复制内核堆
      • childregs->ax = 0; //为什么子进程的fork返回0,这里就是原因!
      • p->thread.sp = (unsigned long) childregs; //调度到子进程时的内核栈顶
      • p->thread.ip = (unsigned long) ret_from_fork; //调度到子进程时的第一条指令地址

 

posted @ 2016-03-28 16:55  20135302魏静静  阅读(216)  评论(1编辑  收藏  举报