进程的描述和进程的创建

一、 进程的描述

(一)进程控制块PCB——task_struct

1、操作系统的三大管理功能包括:

  (1)进程管理

  (2)内存管理

  (3)文件系统

2、PCB task_struct中包含:

  (1)进程状态

  (2)进程打开的文件

  (3)进程优先级信息

3、通过唯一的进程标识PID来区别每个进程。

4、进程控制块PCB——task_struct

5、进程状态

  (1)创建新进程后实际的状态是TASK_RUNNING,就绪但是没有运行,调度器选择一个task之后进入运行态,也叫TASK_RUNNING。

  (2)当进程是TASK_RUNNING时,代表这个进程是可运行的,至于它有没有真的在运行,取决于它有没有获得cpu的控制权,即有没有在cpu上实际的运行。

  (3)一个正在进行的进程调用do_exit(),进入TASK_ZOMBIE,进程被终止,“僵尸进程”。

  (4)等待特定时间或者资源的时候,进入阻塞态,如果条件满足就进入就绪态,被选择后进入运行态。

6、理解task_struct数据结构

  (1)进程的标示pid

  (2)为了对给定类型的进程进行有效的搜索,内核维护了几个进程链表。

  (3)所有进程链表struct list_head tasks

7、CPU相关的状态

二、 进程的创建

(一)进程的创建概览及fork一个进程的用户态代码

1、fork一个子进程的代码:

#include <stdio.h>

#include <stdlib.h>

#include <unistd.h>

int main(int argc, char * argv[])

{

int pid;

/* fork another process */

pid = fork();

if (pid < 0)

{

/* error occurred */

fprintf(stderr,"Fork Failed!");

exit(-1);

}

else if (pid == 0)

{

/* child process */

printf("This is Child Process!\n");

}

else

{

/* parent process  */

printf("This is Parent Process!\n");

/* parent will wait for the child to complete*/

wait(NULL);

printf("Child Complete!\n");

}

}

  (1)fork()系统调用从内核返回两次:一次回到父进程,另一次回到新产生的子进程。

  (2)fork()实际上是由clone()系统调用实现的。

(二)理解进程创建过程复杂代码的方法

1、调用fork的过程:

(三)创建一个新进程在内核中的执行过程

  • fork、vfork和clone三个系统调用都可以创建一个新进程,而且都是通过调用do_fork来实现进程的创建;
  • Linux通过复制父进程来创建一个新进程,那么这就给我们理解这一个过程提供一个想象的框架:
  • 复制一个PCB——task_struct
    1. err = arch_dup_task_struct(tsk, orig);
  • 要给新进程分配一个新的内核堆栈
    1. ti = alloc_thread_info_node(tsk, node);
    2. tsk->stack = ti;
    3. setup_thread_stack(tsk, orig); //这里只是复制thread_info,而非复制内核堆栈
    • 要修改复制过来的进程数据,比如pid、进程链表等等都要改改吧,见copy_process内部。
  • 从用户态的代码看fork();函数返回了两次,即在父子进程中各返回一次,父进程从系统调用中返回比较容易理解,子进程从系统调用中返回,那它在系统调用处理过程中的哪里开始执行的呢?这就涉及子进程的内核堆栈数据状态和task_struct中thread记录的sp和ip的一致性问题,这是在哪里设定的?copy_thread in copy_process
    1. *childregs = *current_pt_regs(); //复制内核堆栈
    2. childregs->ax = 0; //为什么子进程的fork返回0,这里就是原因!
    3. p->thread.sp = (unsigned long) childregs; //调度到子进程时的内核栈顶
    4. p->thread.ip = (unsigned long) ret_from_fork; //调度到子进程时的第一条指令地址

新进程执行起点:return_from_fork,只复制了内核堆栈一部分,int指令和save_all压到内核栈的内容,参数、系统调用号等都进行压栈。

(四)使用gdb跟踪创建新进程的过程

1、准备工作:

  rm menu -rf

  git clone http://github.com/mengning/menu.git   //更新Menu

  cd menu

  mv test_fork.c test.c   //把test.c覆盖掉

  make rootfs

2、进行gdb调试:

  qemu -kernel linux-3.18.6/arch/x86/boot/bzImage -initrd rootfs.img -s -S

  gdb

  file linux-3.18.6/vmlinux

  target remote:1234

  // 设置断点

  b sys_clone  //因为fork实际上是执行的clone

  b do_fork

  b dup_task_struct

  b copy_process

  b copy_thread

  b ret_from_fork

  c

  n

  tsk->stack = ti;    //把内核堆栈的地址赋给它

  sturct pt_regs *childregs = task_pg_regs(p);  //把内核堆栈压栈的空间地址找到,初始化。

  *childregs = *current_pt_regs();

  childregs->ax = 0;  //把当前进程的内核堆栈的压的寄存器赋值到子进程中来。

  p->thread.ip = (unsigned long) ret_from_fork; //设置子进程被调度的ip,即子进程的起点

  jmp syscall_exit;   //这之后就跟踪不到了。

三、总结

  进程就是处于执行期的程序;进程就是正在执行的程序代码的实时结果;进程是处于执行期的程序以及相关的资源的总称。

进程在创建它的时刻开始存活。在Linux系统中,这通常是调用fork()系统的结果。fork()系统调用从内核返回两次:一次回到父进程,另一次回到新产生的子进程。它实际上是由clone()系统调用实现的。

Linux内核分析——进程的描述和进程的创建的更多相关文章

  1. 《Linux内核分析》 第六节 进程的描述和进程的创建

    <Linux内核分析> 第六节 进程的描述和进程的创建 20135307 张嘉琪 原创作品转载请注明出处 +<Linux内核分析>MOOC课程http://mooc.study ...

  2. 《Linux内核分析》第六周 进程的描述与创建

    [刘蔚然 原创作品转载请注明出处 <Linux内核分析>MOOC课程http://mooc.study.163.com/course/USTC-1000029000] WEEK SIX(3 ...

  3. 《Linux内核分析》第八周 进程的切换和系统的一般执行过程

    [刘蔚然 原创作品转载请注明出处 <Linux内核分析>MOOC课程http://mooc.study.163.com/course/USTC-1000029000] WEEK EIGHT ...

  4. Linux内核分析期中总结

    目录: “Linux内核分析”实验一报告 “Linux内核分析”实验二报告 “Linux内核分析”实验三报告 Linux实验四报告 “Linux内核分析”第五周报告 "Linux内核分析&q ...

  5. 《Linux内核分析》课程第三周学习总结

    姓名:何伟钦 学号:20135223 ( *原创作品转载请注明出处*) ( 学习课程:<Linux内核分析>MOOC课程http://mooc.study.163.com/course/U ...

  6. Linux内核分析第六周学习总结:进程的描述和进程的创建

    韩玉琪 + 原创作品转载请注明出处 + <Linux内核分析>MOOC课程http://mooc.study.163.com/course/USTC-1000029000 一.进程的描述 ...

  7. LINUX内核分析第六周学习总结——进程的描述与创建

    LINUX内核分析第六周学习总结--进程的描述与创建 标签(空格分隔): 20135321余佳源 余佳源 原创作品转载请注明出处 <Linux内核分析>MOOC课程 http://mooc ...

  8. LINUX内核分析第六周学习总结——进程的描述和进程的创建

    LINUX内核分析第六周学习总结——进程的描述和进程的创建 张忻(原创作品转载请注明出处) <Linux内核分析>MOOC课程http://mooc.study.163.com/cours ...

  9. 20135239益西拉姆 Linux内核分析 进程的描述和进程的创建

    [益西拉姆 原创作品转载请注明出处 <Linux内核分析>MOOC课程http://mooc.study.163.com/course/USTC-1000029000] 第六周 进程的描述 ...

  10. Linux内核分析——进程描述与创建

    20135125陈智威 原创作品转载请注明出处 <Linux内核分析>MOOC课程http://mooc.study.163.com/course/USTC-1000029000 实验内容 ...

随机推荐

  1. SQL Server2008 18456错误

    1.以windows验证模式进入数据库管理器.   第二步:右击sa,选择属性:   在常规选项卡中,重新填写密码和确认密码(改成个好记的).把强制实施密码策略去掉.   第三步:点击状态选项卡:勾选 ...

  2. 启动Myeclipse报错“Failed to create the Java Virtual Machine”的解决办法

    我安装的是Myeclipse 10.7.1.装上好久没用,今天启动突然报错:Failed to create the Java Virtual Machine. 检查Myeclipse安装好使用时好的 ...

  3. 深入理解Java中的final关键字(转)

    文章转自http://www.importnew.com/7553.html Java中的final关键字非常重要,它可以应用于类.方法以及变量.这篇文章中我将带你看看什么是final关键字?将变量, ...

  4. 【转】Kaggle注册问题-验证码和手机短信

    注册和登录Kaggle时验证码无法显示问题 参考:https://blog.csdn.net/zhuisaozhang1292/article/details/81529981 应用FQ软件需要时时关 ...

  5. 静态分析Android程序

    快速定位Android程序的关键代码 1.通过apktool反编译apk文件,得到AndroidManifest.xml文件,可以得到程序用到的组建.配置.以及主Activity 2.信息反馈法(特殊 ...

  6. PAT A1141 PAT Ranking of Institutions (25 分)——排序,结构体初始化

    After each PAT, the PAT Center will announce the ranking of institutions based on their students' pe ...

  7. python基础学习第四天

    #字符串到数字 可以进行各种进制转换#print(int('11111',8)) #需求 对字符串中的单词翻转 保留空格#第一种方法 最笨clstr='I love you!'bam=clstr.sp ...

  8. linux 用xshell工具远程登录

    1.设置linux,获取ip,登录名.密码 2.xshell登录

  9. STM32F103C8架构

    通常咱们拿到芯片的datasheet第一点需要关注的就是芯片的系统架构.下图就是STM32F103的系统架构图: 首先cortex内核是ARM公司的数字电路流片的产品,数字电路也就是逻辑电路经过FPG ...

  10. jsp中使用原生js实现异步交互

    Ajax的工作原理相当于在用户和服务器之间加了—个中间层,使用户操作与服务器响应异步化.并不是所有的用户请求都提交给服务器,像—些数据验证和数据处理等都交给Ajax引擎自己来做,只有确定需要从服务器读 ...