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加载完成后事件
有这个想法是在很早以前了,那时的我没有接触什么缓存技术,只知道hibernate有个二级缓存.没有用过memcache,也没有使用过redis. 只懂得将数据放到数组里或者集合里,一直不去销毁它(只有 ...
- Weblogic11g下调WebService出现的一系列问题
Weblogic11g下调WebService出现的一系列问题 今天在远程测试机上测试前天写的调用WebService接口方法,遇到的问题还真多啊! 首先说明一下weblogic加载jar包的顺序: ...
- Entity Framework中的Identity map和Unit of Work模式
阅读目录: 一.什么是Identity map模式 二.关于Identity map模式的验证示例 三.Unit of Work 模式 四.总结和注意的问题 一,什么是Identity map模式 I ...
- Effective Java 28 Use bounded wildcards to increase API flexibility
Get and Put Principle PECS stands for producer-extends(? extends T), consumer-super(? super T). For ...
- Progress Control with Text
原文链接:http://www.codeproject.com/Articles/80/Progress-Control-with-Text 重写的Progress 包括,设置bar前景背景颜色,设置 ...
- log4j日志优先级问题的后续
前文:http://www.cnblogs.com/chyu/p/4280440.html 出现一处吐槽失误,当时还想怎么会设置成warn级别.. <appender name="ST ...
- Tomcat 长连接与短连接性能测试
环境: 操作系统:centos 6.5 x64 cpu:32 core 内存: 32G web服务器:tomcat 6.x jdk :1.6x 测试环境: 操作系统:centos 6.5 x64 c ...
- 边工作边刷题:70天一遍leetcode: day 82-1
Closest Binary Search Tree Value II 要点:通过iterator,把closest值附近的k个closest找到,从而time降为O(klgn) in order i ...
- 边工作边刷题:70天一遍leetcode: day 85-3
Zigzag Iterator 要点: 实际不是zigzag而是纵向访问 这题可以扩展到k个list,也可以扩展到只给iterator而不给list.结构上没什么区别,iterator的hasNext ...
- eclipse菜单解释及中英对照《二》
上篇文章主要介绍了eclipse中每个大的标题下的中英文及其用法. 感谢http://blog.csdn.net/li_jinjian2005/article/details/2831641这个博主. ...