20135220谈愈敏Blog6_进程的描述和创建
进程的描述和创建
谈愈敏 原创作品转载请注明出处 《Linux内核分析》MOOC课程 http://mooc.study.163.com/course/USTC-1000029000
进程的描述
操作系统的三大管理功能:
- 进程管理(最重要的)
- 内存管理
- 文件系统
为了管理进程,内核必须对每个进程进行清晰的描述,进程描述符提供了内核所需了解的进程信息。
进程控制块PCB task_struct:
- 进程状态
- 进程打开的文件
- 进程优先级信息
task_struct总体数据结构的抽象:
tty:控制台
fs:文件系统
files:文件描述符
mm:内存管理
signal:信号描述
进程状态:不同于操作系统(就绪、运行、阻塞),如Linux中就绪状态和运行状态都是TASK_RUNNING

进程的标示:pid
进程描述符task_struct数据结构:






进程的创建
进程起源回顾:
道生一(start_kernel....cpu_idle)
一生二(kernel_init和kthreadd)
二生三(即前面0、1和2三个进程)
三生万物(1号进程是所有用户态进程的祖先,2号进程是所有内核线程的祖先)
0号进程,是代码写死的,1号进程复制0号进程PCB,再修改,再加载可执行程序。
fork创建一个子进程
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) //子进程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");
}
}
fork在父进程和子进程各返回一次
子进程中返回的是0,父进程中返回值是子进程的id。
创建一个新进程在内核中的执行过程
fork、vfork和clone三个系统调用都可以创建一个新进程,而且都是通过调用do_fork来实现进程的创建;
Linux通过复制父进程来创建一个新进程:
do_fork主要是复制了父进程的task_struct,然后修改必要的信息,从而得到子进程的task_struct。
理解这一个过程的一个想象的框架:
复制一个PCB——task_struct
err = arch_dup_task_struct(tsk, orig);
要给新进程分配一个新的内核堆栈
ti = alloc_thread_info_node(tsk, node);
tsk->stack = ti;
setup_thread_stack(tsk, orig); //这里只是复制thread_info,而非复制内核堆栈
要修改复制过来的进程数据,比如pid、进程链表等等都要改改吧,见copy_process内部。
新进程从哪里开始执行?
从用户态的代码看fork();函数返回了两次,即在父子进程中各返回一次:
- 父进程从系统调用中返回比较容易理解
- 子进程从系统调用中返回,那它在系统调用处理过程中的哪里开始执行的呢?
这就涉及子进程的内核堆栈数据状态和task_struct中thread记录的sp和ip的一致性问题,这是在哪里设定的?copy_thread in copy_process
*childregs = *current_pt_regs(); //复制内核堆栈
childregs->ax = 0; //为什么子进程的fork返回0,这里就是原因!
p->thread.sp = (unsigned long) childregs; //调度到子进程时的内核栈顶
p->thread.ip = (unsigned long) ret_from_fork; //调度到子进程时的第一条指令地址
fork出来的子进程是从ret_from_fork开始执行的,然后跳转到syscall_exit,从系统调用中返回。
实验:分析Linux内核创建一个新进程的过程
启动MenuOS
cd LinuxKernel
rm menu -rf
git clone https://github.com/mengning/menu.git
cd menu
mv test_fork.c test.c
make rootfs


gdb调试fork命令
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
b do_fork
b dup_task_struct
b copy_process
b copy_thread
b ret_from_fork

跟踪调试:






总结
首先了解了进程控制块PCB,进程描述符task_struct,先从整体抽象概念讲,然后看具体的实现代码,虽然task_struct数据结构很庞大很复杂,我们也要理解一些重点,如进程运行状态、内核堆栈,还有当前CPU相关的一些,文件系统列表,打开的文件描述符等。
关于进程的创建:0号进程,是代码写死的,1号进程复制0号进程PCB,Linux是通过复制父进程来创建一个新进程,然后修改必要的信息,从而得到子进程的task_struct。
fork创建的新的子进程是从ret_from_fork开始执行的,然后跳转到syscall_exit,从系统调用中返回。新进程如何开始执行的关键:
p->thread.sp = (unsigned long) childregs; //调度到子进程时的内核栈顶
p->thread.ip = (unsigned long) ret_from_fork; //调度到子进程时的第一条指令地址
20135220谈愈敏Blog6_进程的描述和创建的更多相关文章
- 20135220谈愈敏Blog8_进程的切换和系统的一般执行过程
进程的切换和系统的一般执行过程 谈愈敏 原创作品转载请注明出处 <Linux内核分析>MOOC课程 http://mooc.study.163.com/course/USTC-100002 ...
- 20135220谈愈敏Blog2_操作系统是如何工作的
操作系统是如何工作的 谈愈敏 原创作品转载请注明出处 <Linux内核分析>MOOC课程http://mooc.study.163.com/course/USTC-1000029000 计 ...
- 20135220谈愈敏Blog7_可执行程序的装载
可执行程序的装载 谈愈敏 原创作品转载请注明出处 <Linux内核分析>MOOC课程 http://mooc.study.163.com/course/USTC-1000029000 一. ...
- 20135220谈愈敏Blog3_构造一个简单的Linux系统MenuOS
构造一个简单的Linux系统MenuOS 谈愈敏 原创作品转载请注明出处 <Linux内核分析>MOOC课程 http://mooc.study.163.com/course/USTC-1 ...
- 20135220谈愈敏Blog4_系统调用(上)
系统调用(上) 谈愈敏 原创作品转载请注明出处 <Linux内核分析>MOOC课程 http://mooc.study.163.com/course/USTC-1000029000 用户态 ...
- 20135220谈愈敏Blog5_系统调用(下)
系统调用(下) 谈愈敏 原创作品转载请注明出处 <Linux内核分析>MOOC课程 http://mooc.study.163.com/course/USTC-1000029000 给Me ...
- 20135220谈愈敏Linux_总结
Linux_总结 具体博客链接 计算机是如何工作的 操作系统是如何工作的 构造一个简单的Linux系统MenuOS 系统调用(上) 系统调用(下) 进程的描述和创建 可执行程序的装载 进程的切换和系统 ...
- 20135220谈愈敏Linux Book_4
进程调度 进程:程序的运行态表现形式 进程调度程序:确保进程能有效工作的一个内核子系统,决定将哪个进程投入运行.何时运行以及运行多长时间,在可运行态进程之间分配有限的处理器时间资源. 最大限度的利用处 ...
- 20135220谈愈敏Linux Book_3
第3章 进程管理 进程是Unix操作系统抽象概念中最基本的一种,进程管理是操作系统的心脏所在. 3.1 进程 进程:处于执行期的程序以及相关的资源的总称. 线程:在进程中活动的对象,拥有独立的程序计数 ...
随机推荐
- Spring、SpringMVC、Mybaitis框架配置
给大家推荐2个网址,介绍的非常详细 SSM环境搭建 http://blog.csdn.net/zhshulin/article/details/37956105 SSM代码生成工具介绍 http:// ...
- python sorted
python列表排序 python字典排序 sorted List的元素可以是各种东西,字符串,字典,自己定义的类等. sorted函数用法如下: sorted(data, cmp=None, key ...
- ASCII
0. American Standard Code of Information Interchange 美国信息交换标准码, 即ASCII, 定义表如下: Bin(二进制) Oct(八进制) Dec ...
- delete_old_backup.bat
在前面forfiles命令批量删除N天前文件 这篇文章里面讲述了如何在SQL Server 2000中使用forfile删除N天前备份文件,但是现在又有新需求: 需求描述:通过数据库维护计划将备份生成 ...
- nginx 与 lua 开发环境搭建
首先下载最新版的 相关软件 的安装文件. nginx: http://nginx.org/en/download.html LuaJIT: http://luajit.org/download.htm ...
- JQ插件
什么是插件 插件(plugin)是JQuery的扩展(Extension),以JQuery的核心代码为基础,是一种遵循一定规范的应用程序接口编写出来的程序. 插件的引入 引入jquery.js文件 引 ...
- 用WPF做了几个小游戏
最近看书看累了,参考别人的代码(其实差不多就是把代码重新打了一遍o(╯□╰)o),用wpf做了个<2048>小游戏,顺便在<Git教程>学习下git,也顺便把在<写让别人 ...
- [工具] 分布式系统下批量创建用户及分发公钥打通ssh通道的脚本
在分布式系统下偶尔会有这样的需求,要增加一个服务时,需要在集群的所有节点上创建同一个用户,然后打通ssh通道,再分发软件包.配置.执行命令.启动服务... 这个问题的根源是如何集中配置和管理系统,专业 ...
- 开创学习的四核时代-迅为iTOP4412学习开发板
产品特点: 处理器: Exynos 4412 处理器,Cortex-A9四核,功耗性能俱佳! 性能: 1GB(可选2GB) 双通道 64bit数据总线 DDR3: 4GB(可选16GB)固态硬盘EMM ...
- ETL from hadoop to vertica
根据项目需要,我做了一个POC(proof of concept),XML TXT的数据从HADOOP 引入到VERTICA. 我采用的方案是pig,具体信息可以参加vertica官方的文档. Acc ...