操作系统内核实现操作系统的三大管理功能以及对应的抽象概念:
进程是怎样描述的?
Linux内核中用数据结构 struct task_struct 来描述进程,称其为进程描述符。
进程描述符的结构示意图:
Linux内核管理的进程状态转化图:
注意:操作系统原理中就绪态和运行态这两个状态在Linux内核中都是相同的 TASK_RUNNING 状态。在Linux内核中,当进程是 TASK_RUNNING 状态时,它是可运行的,也就是就绪态,是否运行取决于它有没有获得CPU的控制权。
阻塞态也有两种:TASK_INTERRUPTIBLE 和 TASK_UNINTERRUPTIBLE 。
进程标识符PID。在进程描述符中用pid和tgid标识进程。
管理进程数据结构的双向链表:struct list_head tasks (是一个很关键的进程链表)
1301 struct mm_struct *mm,*active_mm;
mm 和 active_mm 是和进程地址空间,内存管理相关的数据结构指针。
rest_init 通过 kernel_thread 创建两个内核线程:
fork,vfork,clone 三个系统调用都可以创建一个新进程,而且都可通过调用 do_fork 来实现进程的创建。
fork 一个子进程的过程中,复制父进程的资源采用了Copy On Write(写时复制)技术。不需要修改进程资源,父子进程是共享内存存储空间的。
进程创建的过程:
进程创建过程中的重要函数或数据结构:
删掉menu之后克隆一份新的,把test.c覆盖掉,在menu下面执行 make roofts 。
编译运行出来可以看到列表中增加了fork。下图是 MenuOS 的运行效果。执行fork可以看到父进程和子进程都输出信息。
启动gdb,把内核加载进来,连接到target remote 1234
在sys_clone、do_fork、dup_task_struct、copy_process、copy_thread、ret_from_fork处各设置断点。
继续执行,停到了 do_fork 位置,next
到 copy_process() 函数。继续执行
继续执行,到copy_thread:
涉及 system_call 的那段段汇编代码跟踪不到。
1.在Linux中,fork()系统调用产生的子进程在系统调用处理过程中从何处开始执行?
从用户态空间来看,就是fork系统调用的下一条指令。
子进程和父进程都从调用fork函数的下一条语句开始执行
2.fork调用的特性“一次调用,两次返回”,它可能有三种不同的返回值:
1)在父进程中,fork返回新创建子进程的进程pid(返回值>0);
2)在子进程中,fork返回0;
3)如果出现错误,fork返回一个负值。
创建新进程成功后,系统中出现两个基本完全相同的进程,这两个进程执行没有固定的先后顺序,哪个进程先执行要看系统的进程调度策略。此时,两个进程都从fork开始往下执行,只是pid不同。
3.父进程和新创建的子进程之间最大区别在于他们有着不同的PID。
4.所有的子进程是在do_fork实现创建和调用的。
5.对后面的跟踪状态还不太懂,等弄清楚了再进行补充。
参考资料:https://blog.csdn.net/zxm342698145/article/details/56513252
https://blog.csdn.net/Always2015/article/details/45008785?locationNum=9&fps=1
手机扫一扫
移动阅读更方便
你可能感兴趣的文章