gdb调试执行流程,首先设置断点b sys_clone,当在shell下输入fork命令后,系统执行至断点,接下来按步执行:
  1. 判断是否被跟踪
  2. 判断是否被创建为轻量级进程(vfork)
  3. 判断父进程是否被跟踪,
  4. 判断是否子进程获取新的PID或命名空间,如果是,则不允许其共享进程组、信号handler或父进程
  5. task_create在复制之前确认共享的权限
  6. 调用dup_task_struct复制task_struct(进程描述符)
  7. alloc_task_struct_node为task_struct分配内存
  8. alloc_thread_info_node为thread_info分配内存
  9. setup_thread_stack为进程新建一个内核栈
  10. copy_semundo
  11. copy_files
  12. copy_fs
  13. copy_sighand
  14. copy_signal
  15. copy_mm
  16. copy_namespaces
  17. copy_io
  18. 进入copy_thread
  19. struct pt_regs *childregs = task_pt_regs(p);给指针赋值,指向.thread.regs
  20. *childregs = *current_pt_regs();复制寄存器内容
  21. childregs->ax = 0; 给子进程pid返回值0;
  22. p->thread.ip = (unsigned long)ret_from_fork;子进程从ret_from_fork开始执行。
  23. ret_from_fork位于entry.S。子进程执行ret_from_fork后转到syscall_exit
  24. 父进程copy_thread完成,返回copy_process
  25. 给新进程分配新pid
  26. 设置子进程pid
  27. 子进程接下来进行关中断,检查信号(信号量不共享则不复制),继续restore_all最后恢复上下文,从内核态返回,继续执行程序中的代码。
  28. 父进程返回sys_clone,父进程执行fork()之后的代码。最后程序结束。
总结:
  • 进程(task)是处于执行期的程序,通常还包括打开的文件,挂起的信号,内核内部数据,处理器状态,一个或多个具有内存映射的内存地址空间及一个或多个执行线程,还有存放全局变量的数据段等。
  • 线程是在进程中活动的对象。linux:不特别区分进程线程,线程是特殊的进程。
  • 在现代Linux内核中,fork实际上是由clone系统调用实现的。
  • fork从内核返回两次,一个回到父进程,一次回到产生的新的子进程。
  • 程序通过exit()系统调用退出执行。此函数会终结进程并将其占用的资源释放掉。父进程可以通过wait4()系统调用查询子进程是否终结,这使进程拥有了等待特定进程执行完毕的能力。进程退出执行后被设置僵死状态。
  • Linux系统通过c库提供wait(),waitpid(),wait3(),wait4()等函数。
  • 内核把进程的列表存放在任务队列(task list)双向列表中,表中每项都是task_struct,被称为进程描述符,定义在<linux/sched.h>中。内核通过一个唯一的进程标示值PID来标记进程。PID为pid_t类型,实际为int。
  • 进程状态:
    • TASK_RUNNING表示进程可执行。
    • TASK_INTERRUPTIBLE可中断。进程正在睡眠(阻塞),等待信号。
    • TASK_UNINTERRUPTIBLE不可中断。处于此状态不受信号唤醒。其它同上。
    • _TASK_TRACED被其他进程跟踪的进程。
    • _TASK_STOPPED进程没有投入运行也不能投入运行。
  • Unix将产生机制分解为fork和exec。fork复制exec负责读取可执行文件并将其载入地址空间开始运行。
  • fork采用写时拷贝页实现。页的拷贝推迟到实际发生写入时。
  • 内核有意选择子进程先执行,因为一般子进程马上会调用exec()。以避免写时拷贝的开销。
  • 完成fork调用后存在两个进程,每个进程都会从fork()返回处继续执行。
  • fork,vfork,clone都调用do_fork,vfork不拷贝父进程的页表。clone带参数。

参考文献:

《Linux内核设计与实现》

By:昆仑雪狐

原创作品转载请注明出处

《Linux内核分析》MOOC课程http://mooc.study.163.com/course/USTC-1000029000

fork函数创建新进程过程分析的更多相关文章

  1. 通过fork函数创建进程的跟踪,分析linux内核进程的创建

    作者:吴乐 山东师范大学 <Linux内核分析>MOOC课程http://mooc.study.163.com/course/USTC-1000029000 一.实验过程 1.打开gdb, ...

  2. Linux内核分析— —创建新进程的过程

    分析Linux内核创建一个新进程的过程 实验过程 要求:使用gdb跟踪分析一个fork系统调用内核处理函数sys_clone ,验证对Linux系统创建一个新进程的理解,推荐在实验楼Linux虚拟机环 ...

  3. linux进程学习-创建新进程

    init进程将系统启动后,init将成为此后所有进程的祖先,此后的进程都是直接或间接从init进程“复制”而来.完成该“复制”功能的函数有fork()和clone()等. 一个进程(父进程)调用for ...

  4. linux里面的fork函数创建一个新进程

    由fork创建的新进程成为子进程,fork函数被调用一次,但是返回两次,

  5. 创建新进程,就三个函数CreateProcessAsUser CreateProcessWithLogonW CreateProcessWithTokenW(附网友的流程)

    CreateProcessAsUser 怎么会还需要密码呢~~~ 先WTSGetActiveConsoleSessionId 得到当前的处理激活状态的SessionId OpenProcessToke ...

  6. Linux内核分析-创建新进程的过程

    分析Linux内核创建一个新进程的过程 task_struct结构体分析 struct task_struct{ volatile long state; //进程的状态 unsigned long ...

  7. Go:创建新进程(os.StartProcess源码解读)

    关于如何使用go语言实现新进程的创建和进程间通信,我在网上找了不少的资料,但是始终未能发现让自己满意的答案,因此我打算自己来分析这部分源代码,然后善加利用,并且分享给大家,期望大家能从中获得启发. 首 ...

  8. Win32 API编程:使用CreateProcess创建新进程

    #include <windows.h> #include <tchar.h> #include <stdio.h> int main(int argc, char ...

  9. 第八篇:文件共享和使用 dup 函数创建新描述符的区别

    前言 文件共享是指同时打开一个文件 用 dup 函数能对指定文件描述符再创建一个新的描述符,且这个新的描述符和旧的描述符指向的是同一个文件. 这两种行为有什么区别呢?下面给出的两张文件系统的图形象的解 ...

随机推荐

  1. 个人介绍和Github使用流程

    我叫石莉静,来自网络工程143班,学号1413042067 我的兴趣爱好有看电影.动漫,听音乐,摄影,寻找美食等等. 个人编程能力:非常真诚的说,我的编程能力蛮差的,用C++写过一共写过...(很少很 ...

  2. 苹果下如果安装nginx,给nginx安装markdown第三方插件

    用brew install nginx 这样安装的是最新版的nginx, 但是在有些情况下,安装第三方插件需要特定的版本,更高一级的版本可能装不上. 它的原理是下载安装包进行自动安装,建立软链,这样就 ...

  3. JBoss-7.1.1 http访问端口修改

    修改http服务端口 找到 jboss-as-7.1.1.Final/standalone/configuration/standalone.xml文件,找到第298行,如下图: 如果我们想改成80端 ...

  4. 获取下拉框的文本值和value值

    http://www.cnblogs.com/djgs/p/3691979.html?utm_source=tuicool&utm_medium=referral 现在有一个Id为AreaId ...

  5. curl --connect-timeout 判断国内外网络windows 批处理

    1.下载编译curl curl 下载地址:http://curl.haxx.se/download.html ,下载后解压到一个目录,使用vs开发者工具里的 “Visual Studio 命令提示(2 ...

  6. iOS多线程中performSelector: 和dispatch_time的不同

    iOS中timer相关的延时调用,常见的有NSObject中的performSelector:withObject:afterDelay:这个方法在调用的时候会设置当前runloop中timer,还有 ...

  7. 第二讲(核心c#)

    一.C#类型 .字段和局部变量的作用域冲突 using System; namespace Wrox { public class ScopeTest2 { ; public static void ...

  8. Bootstrap<基础十> 响应式实用工具

    Bootstrap 提供了一些辅助类,以便更快地实现对移动设备友好的开发.这些可以通过媒体查询结合大型.小型和中型设备,实现内容对设备的显示和隐藏. 需要谨慎使用这些工具,避免在同一个站点创建完全不同 ...

  9. node模块系统常用命令

    node模块系统常用命令 命令 示例 备注 安装模块 npm install commander 最新版本 npm install commander@1.0.0 指定版本 npm install c ...

  10. ASP.NET简单实现APP中用户个人头像上传和裁剪

    最近有个微信项目的用户个人中心模块中,客户要求用户头像不仅仅只是上传图片,还需要能对图片进行裁剪.考虑到flash在IOS和Android上的兼容性问题,于是想着能从js这块入手,在网上发现了devo ...