首页 技术 正文
技术 2022年11月21日
0 收藏 879 点赞 4,867 浏览 1617 个字

进程的描述和进程的创建

一、进程的描述

操作系统三大功能:

  • 进程管理
  • 内存管理
  • 文件系统

进程描述符task_struct数据结构

  • task _ struct:为了管理进程,内核必须对每个进程进行清晰的描述,进程描述符提供了内核所需了解的进程信息。

  • 进程的状态:Linux进程的状态(就绪态、运行态、阻塞态)

  • 进程的标示pid:用来标示进程

20135327郭皓–Linux内核分析第六周 进程的描述和进程的创建

进程描述符task_struct数据结构(重要部分):

 struct task_struct {
volatile long state; /* 进程的运行状态-1 unrunnable, 0 runnable, >0 stopped */
void *stack; /*指定了进程的内核堆栈*/
atomic_t usage;
unsigned int flags; /* 每一个进程的标识符 */ int on_rq; /*运行队列*/ pid_t pid; /*进程标识符*/ struck list_head task; /*进程链表*/ /*父子进程*/
struct task_struct __rcu *real_parent; /* real parent process */
struct task_struct __rcu *parent; struct list_head children; /* list of my children */

二、进程的创建

start _ kernel代码中的rest _ init创建两个内核线程,kernel _ init和kthreadd。

kernel _ init将用户态进程init启动,是所有用户态进程的祖先。

kthreadd是所有内核线程的祖先。

0号进程是所有线程的祖先。(0号进程时手工写的)

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 < )
{
/* error occurred */
fprintf(stderr,"Fork Failed!");
exit(-);
}
else if (pid == )
{
/* 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");
}
}

这里特别说明一下:else if和if两个模块的代码都会被执行,子进程和父进程都会返回,子进程返回0,父进程返回子进程pid。

实验:

1. 删除menu,克隆新的menu。

20135327郭皓–Linux内核分析第六周 进程的描述和进程的创建

2.查看help

20135327郭皓–Linux内核分析第六周 进程的描述和进程的创建

3.gdb调试

20135327郭皓–Linux内核分析第六周 进程的描述和进程的创建

4.设置断点

20135327郭皓–Linux内核分析第六周 进程的描述和进程的创建

5.单步追踪

20135327郭皓–Linux内核分析第六周 进程的描述和进程的创建

20135327郭皓–Linux内核分析第六周 进程的描述和进程的创建

20135327郭皓–Linux内核分析第六周 进程的描述和进程的创建

20135327郭皓–Linux内核分析第六周 进程的描述和进程的创建

总结:

新的进程从哪里开始?

 *childregs = *current_pt_regs(); //复制内核堆栈
childregs->ax = ; //为什么子进程的fork返回0,这里就是原因! p->thread.sp = (unsigned long) childregs; //调度到子进程时的内核栈顶
p->thread.ip = (unsigned long) ret_from_fork; //调度到子进程时的第一条指令地址

Linux通过复制父进程来创建一个新进程:复制父进程PCB–task_struct来创建一个新进程,要给新进程分配一个新的内核堆栈。

修改复制过来的进程数据,比如pid、进程链表等等执行copy_process和copy_thread。

设置sp调度到子进程时的内核栈顶,ip转到子进程时的第一条指令地址

之后,当子进程获得CPU的控制权开始运行的时候,ret _ form _ fork可以将后面的堆栈出栈,从iret返回到用户态,从而切换到子进程的用户空间,完成新进程的创建。

相关推荐
python开发_常用的python模块及安装方法
adodb:我们领导推荐的数据库连接组件bsddb3:BerkeleyDB的连接组件Cheetah-1.0:我比较喜欢这个版本的cheeta…
日期:2022-11-24 点赞:878 阅读:8,987
Educational Codeforces Round 11 C. Hard Process 二分
C. Hard Process题目连接:http://www.codeforces.com/contest/660/problem/CDes…
日期:2022-11-24 点赞:807 阅读:5,503
下载Ubuntn 17.04 内核源代码
zengkefu@server1:/usr/src$ uname -aLinux server1 4.10.0-19-generic #21…
日期:2022-11-24 点赞:569 阅读:6,347
可用Active Desktop Calendar V7.86 注册码序列号
可用Active Desktop Calendar V7.86 注册码序列号Name: www.greendown.cn Code: &nb…
日期:2022-11-24 点赞:733 阅读:6,130
Android调用系统相机、自定义相机、处理大图片
Android调用系统相机和自定义相机实例本博文主要是介绍了android上使用相机进行拍照并显示的两种方式,并且由于涉及到要把拍到的照片显…
日期:2022-11-24 点赞:512 阅读:7,765
Struts的使用
一、Struts2的获取  Struts的官方网站为:http://struts.apache.org/  下载完Struts2的jar包,…
日期:2022-11-24 点赞:671 阅读:4,842