Linux操作系统 进程管理剖析
意到,当前的任务是 insmod,这是 init_module 函数是在 insmod 命令执行的上下文运行的.current 符号实际指的是一个函数(get_current)并可在一个与 arch 有关的头部中找到(比如 ./linux/include/asm-i386/current.h 内找到).
进程创建 让我们不妨亲自看看如何从用户空间创建一个进程.用户空间任务和内核任务的底层机制是一致的,二者最终都会依赖于一个名为 do_fork 的函数来创建新进程.在创建内核线程时,内核会调用一个名为 kernel_thread 的函数(参见 ./linux/arch/i386/kernel/process.c),此函数执行某些初始化后会调用 do_fork.
创建用户空间进程的情况与此类似.在用户空间,一个程序会调用 fork,这会导致对名为 sys_fork 的内核函数的系统调用(参见 ./linux/arch/i386/kernel/process.c).函数关系如图 1 所示.
从图 1 中,可以看到 do_fork 是进程创建的基础.可以在 ./linux/kernel/fork.c 内找到 do_fork 函数(以及合作函数 copy_process). do_fork 函数调用 alloc_pidmap,该调用会分配一个新的 PID.接下来,do_fork 检查调试器是否在跟踪父进程.如果是,在 clone_flags 内设置 CLONE_PTRACE 标志以做好执行 fork 操作的准备.之后 do_fork 函数还会调用 copy_process,向其传递这些标志、堆栈、注册表、父进程以及最新分配的 PID. 新的进程在 copy_process 函数内作为父进程的一个副本创建.此函数能执行除启动进程之外的所有操作,启动进程在之后进行处理.copy_process 内的第一步是验证 CLONE 标志以确保这些标志是一致的.如果不一致,就会返回 EINVAL 错误.接下来,询问 Linux Security Module (LSM) 看当前任务是否可以创建一个新任务.要了解有关 LSM 在 Security-Enhanced Linux (SELinux) 上下文中的更多信息,请参见 参考资料 小节. 接下来,调用 dup_task_struct 函数(在 ./linux/kernel/fork.c 内),这会分配一个新 task_struct 并将当前进程的描述符复制到其内.在新的线程堆栈设置好后,一些状态信息也会被初始化,并且会将控制返回给 copy_process.控制回到 copy_process 后,除了其他几个限制和安全检查之外,还会执行一些常规管理,包括在新 task_struct 上的各种初始化.之后,会调用一系列复制函数来复制此进程的各个方面,比如复制开放文件描述符(copy_files)、复制符号信息(copy_sighand 和 copy_signal)、复制进程内存(copy_mm)以及最终复制线程(copy_thread).
之后,这个新任务会被指定给一个处理程序,同时对允许执行进程的处理程序进行额外的检查(cpus_allowed).新进程的优先级从父进程的优先级继承后,执行一小部分额外的常规管理,控制也会被返回给 do_fork.在此时,新进程存在但尚未运行.do_fork 函数通过调用 wake_up_new_task 来修复此问题.此函数(可在 ./linux/kernel/sched.c 内找到)初始化某些调度程序的常规管理信息,将新进程放置在运行队列之内,然后将其唤醒以便执行.,一旦返回至 do_fork,此 PID 值即被返回给调用程序,进程完成. 进程调度 存在于 Linux 的进程也可通过 Linux 调度程序被调度.虽然调度程序超出了本文的讨论范围,但 Linux 调度程序维护了针对每个优先级别的一组列表,其中保存了 task_struct 引用.任务通过 schedule 函数(在 ./linux/kernel/sched.c 内)调用,它根据加载及进程执行历史决定最佳进程.在本 |
|||
凌众科技专业提供服务器租用、服务器托管、企业邮局、虚拟主机等服务,公司网站:http://www.lingzhong.cn 为了给广大客户了解更多的技术信息,本技术文章收集来源于网络,凌众科技尊重文章作者的版权,如果有涉及你的版权有必要删除你的文章,请和我们联系。以上信息与文章正文是不可分割的一部分,如果您要转载本文章,请保留以上信息,谢谢! |