进程2的创建与执行
来源:互联网 发布:苹果mac 笔记本电脑 编辑:程序博客网 时间:2024/04/29 19:49
进程1第一次执行,完成设置硬盘信息、格式化虚拟盘(根设备)、加载根文件系统后会回到下面语句:
if(!fork()) {
init();
if(!fork()) {
init();
}
//===================================== 分隔符 ==========================================----init(); 1.打开终端设备文件 ----open("/dev/tty0",O_RDWR,0); //创建标准输入设备,其中/dev/tty0是该文件的路径名 ----sys_open("/dev/tty0",O_RDWR,0); //通过int 0x80中断进行系统调用 ----open_namei("/dev/tty0",O_RDWR,0,&inode);////获取文件tty0的i节点,保存在inode中 ----dir_namei("/dev/tty0",&namelen,&basename); //获取枝梢i节点,namelen为tty0的长度,basename指向tty0的第一个字母't' ----get_dir("/dev/tty0"); //遍历整个文件路径"/dev/tty0",获取枝梢i节点(即获取dev目录文件的i节点) ----find_entry(&inode,thisname,namelen,&de); //根据根i节点和dev来查找dev目录项,此时thisname为dev,namelen=3 ----iget(idev,inr); //根据dev的i节点号获取dev的i节点 ----find_entry(&dir,basename,namelen,&de); //根据dev的i节点和"tty0"来查找tty0的目录项,de指向tty0目录项 ----//检查tty0文件的i节点属性,确定它是一个字符设备文件 ----//设置file_table[0] //至此进程1的current->filp[0]存放的file_table第一个元素地址,file_table第一个元素,又存放着inode的地址,f_count为1,完成标准输入设备/dev/tty0的创建 2.打开标准输出、标准错误输出文件 ----(void)dup(0); //复制句柄,构建标准输出设备 ----(void)dup(0); //继续复制句柄,构建标准错误输出设备 ----sys_dup(0); //dup对应的系统调用函数 ----dupfd(0,0); //执行复制句柄 //执行两次dup(0),将flip[0]中存储的tty0文件指针复制进flip[1]和filp[2],并将file_table[0]中的f_count文件引用计数自增1(两次累加后,f_count为3) //至此,创建shell所需要的终端标准输入设备文件、标准输出设备文件和标准错误输出设备文件读已经打开 3.进程1创建进程2并切换到进程2 ----if(!pid=fork()) //进程1创建进程2(执行过程参考进程1的创建与轮转:http://blog.csdn.net/yang2011079080010/article/details/52947247),进程2创建完毕后,fork()函数返回2,不会执行if中的语句,跳到wait(&i)执行 ----wait(&i) //进程1等待子进程退出,最终会切换到进程2执行 ----sys_waitpid(pid_t pid,unsigned long * stat_addr, int options); //先遍历所有进程,找出进程1的子进程,即进程2,再对进程2进行分析,确定进程2并不准备退出,于是设置flag标志为1,该标志将导致进程切换 ----schedule(); //在调用schedule()函数之前,先将进程1设为可中断状态,然后调用schedule()切换到进程2取执行 ----close(0); //切换到进程2执行(进程1的创建与轮转:http://blog.csdn.net/yang2011079080010/article/details/52947247),确定if(!(pid=fork())这条语句为真后,调用close(0)函数来关闭标准输入输出设备文件,并用rc文件代替 ----sys_close(0); //sys_close(0)是close(0)的系统调用,close(0)就是要将filp[20]第一项清空(就是关闭标准输入设备文件tty0),并递减file_table[64]中f_count的引用计数 ----open("/etc/rc",O_EDONLY,0); //rc文件代替tty0设备文件 ----execve("/bin/sh",argv_rc,envp_rc); //加载shell程序 ----sys_execve(); //execve()的系统调用 ----do_execve() //do_execve是加载shell程序的主体函数,其路径:fs/exec.c,执行过程参考http://blog.csdn.net/jltxgcy/article/details/43560229 .... 4.执行shell程序 do_execve()函数执行完后,sys_execve便会中断返回,去执行shell程序。由于在do_execve中清空了页目录表和对应页表,所以会产生一个"页异常"中断,此中断会进一步调用"缺页中断"处理程序来分配该页面,并加载一页shell程序 //代码路径:mm/page.s ---- _page_fault: //页异常处理函数入口 ----do_no_page(); //调用"缺页中断"处理程序来分配该页面,并加载一页shell程序 ----get_free_page(); //为shell程序申请一页新的内存 ----nr[i] = bmap(current->executable,block); //得到执行的代码所在的块号 ----bread_page(page,current->executable->i_dev,nr); //读取4个逻辑块(1页)的shell程序内容进内存页面 ----put_page(page,address); //物理地址映射到线性地址,建立页目录表--->页表--->页表--->页面的三级映射管理关系 5.切换到shell进程执行,创建update进程(进程3) sheel程序开始执行后,要读取标准输入设备文件上的信息,即task_struct中filp[20]第一项对应的文件信息。参考前面分析知道,此时filp[20]中第一项对应文件是rc而非tty0,因此shell先读取rc ----read(); //shell程序调用read()读取rc文件上的内容 ----sys_read();read()函数的系统调用 ----file_read(inode,file,buf,count); //rc是普通文件,读取结束后,返回值是-ERROR,会导致shell进程退出,退出将执行exit() ---- /etc/update & ... //创建一个新进程update,并加载update程序,update进程完成:将缓存区中的数据同步到外设,由于数据交换速度远低于数据处理速度,数据不是直接写到外设,而是先写入缓存区再同步到外设, //因此每隔一段时间,update就会被唤醒,然后完成一次数据同步,没有同步任务时,update进程会被休眠 ..... ---- echo "/dev/hd1">/etc/mtab //将"/dev/hd1"这一字符串写入虚拟盘中/etc/mtab中 ----exit(); ----sys_exit(); ----do_exit(); //为shell退出做善后工作:释放shell进程代码段和数据段所占用的内存页面、将update进程的父进程设置为进程1、解除shell进程与其他进程、文件、终端等的关系、将当前进程(进程2)设置为僵死状态 //给进程1发信息,通知它shell进程即将退出、进程切换 ----free_page_tables(); //释放shell进程代码段和数据段所占用的内存页面 ----tell_father(current->father); //给进程1发信息,通知它shell进程即将退出 ----schedule(); //进程切换 ----sys_waitpid(); //进程1是执行sys_waitpid()函数时调用schedule()函数切换到进程2的,所以shell进程退出时执行schedule,会最终回到sys_waitpid(),继续shell进程退出的善后工作 //sys_waitpid()执行完后最终会回到init(),因创建完进程2后,pid=2,而sys_wait返回值也是2,即wait()返回值为2,while循环条件为假,跳出while循环。 6.重建shell 进程1回到init()继续执行,准备重建shell ----init(); //回到init()中,准备重建shell ----pid=fork(); //进程1创建进程4,即重建shell进程 ----close(0);close(1);close(2); //关闭所有打开文件 ----setsid(); //创建新的会话 ----(void) open("/dev/tty0",O_RDWR,0); //重新打开标准输入设备文件 ----(void) dup(0); //重新打开标准输出设备文件 ----(void) dup(0); //重新打开标准错误输出设备文件 ----_exit(execve("/bin/sh",argv,envp)); //加载shell进程 .... ----sys_read(); //shell读取的tty0文件为字符设备文件 ----rw_char(); //进入shell进程,shell进程将被设置为可中断等待状态,这样所有的进程全部都处于可中断等待状态,再次切换到进程0取执行,系统实现怠速 ----while(1) if(pid == wait(&i)) //进程1等待子进程退出 break;
0 0
- 进程2的创建与执行
- 浅谈进程2--进程优先级,进程的创建执行
- 【进程管理】进程三部曲:创建,执行与消亡(综述)
- 【Linux】进程的创建执行和优先级
- windows创建一个执行可执行文件的进程!
- 实验0 Linux用户界面的使用 实验一 进程的创建与并发执行
- 进程控制:创建执行其他程序的进程
- 2、进程的创建
- Linux内核设计的艺术-进程2的创建及执行
- 关于fork的创建,子进程的执行
- 八、用户进程:TSS、用户进程的创建、用户进程的执行(通过调度函数)
- c++创建进程执行文件
- 使用VC创建进程和执行命令行程序的方法
- Window下创建进程和执行命令行程序的方法
- 第8节 进程的创建和执行
- 《linux下进程的创建,执行,监控和终止》
- mysql 的 job创建与执行 - event
- mysql 的 job创建与执行 - event
- nginx基本概念介绍
- XILINX FPGA时钟资源
- java高并发解决方案
- ACL 2016&2015 Accepted Papers
- getopts函数中使用
- 进程2的创建与执行
- 【expect】使用心得
- Java之怎么通过java去调用并执行shell脚本以及问题总结(转)
- 个人博客的SEO优化
- 字符串中第一个字符出现的位置
- 生活随笔:开发资金紧张
- “接力者”王川
- Linux环境变量PATH的增添和删除操作
- 个人C语言笔记