读核日记fork上篇

本文对Linux和Unix中fork函数进行代码分析。作者参考多份资料,指出系统调用时函数名可能因函数映射。介绍了fork大体流程,对比Linux和Unix实现,认为Unix更简单清晰。还详细分析了do_fork函数的源代码,包括参数、进程复制及唤醒等操作。

作者:handi
星期四, 十月 28, 2004

读核日记fork上篇

 

中间会参考到一些资料和文章,我也会在日记头一一列出
1. lion's unix 源代码分析
2. kernel 2.6.8 /kernel/fork.c
3. kernel 2.4.18 /kernel/fork.c
4. linux情景分析(上、下)

 

 

基本上没有找到以fork命名的函数,而且还符合
match case and match whold word only

于是sys_fork --> do_fork,就像socket一样只有sys_socket
至于为什么系统调用的时候是fork()和socket(),我想可能是函数map的
原因吧

先说大体流程,之后再解说代码
first,检查一些状态,获取一些必要的信息
--> 进入copy_process实体,复制进程(中间有一个很重要的一点,就是
为什么子进程返回值是0)
--> 设置一些信息
--> 让进程开始run

比较于unix的实现,我只能说linux真复杂和罗嗦,lion's unix
中的实现很简单清晰,如果只是要了解原理的,那份fork就足够了,而且
很老实的,没有sys_fork, v_fork, do_fork之类的嵌套,就一个fork

当然不清楚目前unix的版本中这是怎样实现的,所以过些天会找些minix
或bsd中实现的代码来参考,然后补充到日记中来


前面罗嗦了这么多,还是来分析一下源代码吧.
/kernel/fork.c

kernel_thread(),sys_fork(),sys_clone(),sys_vfork()
这几个函数都是调用do_fork()函数,主要参数区别都是集中在
clone_flags上面,在/arch/i386/kernel/process.c


/*
 *  Ok, this is the main fork-routine.
 *
 * It copies the process, and if successful kick-starts
 * it and waits for it to finish using the VM if required.
 */
long do_fork(unsigned long clone_flags,         /* 克隆标识 */
       unsigned long stack_start,        /* 栈起始位置 - 怎么不用指针? */
       struct pt_regs *regs,             /* 寄存器 */
       unsigned long stack_size,         /* 栈大小 */
       int __user *parent_tidptr,        /* 父进程的什么指针 */
       int __user *child_tidptr)         /* 子进程的什么指针, 这两个指针用来指什么? */
{
 struct task_struct *p;  /* PCB结构 */
 int trace = 0;
 long pid;

        /* CLONE_PTRACE 这个宏表示什么意思[set if we want to let tracing continue on the child too]
         * 翻译过来的意思是如果想跟踪子进程的信息,就设置这一位
         * 是否跟踪由do_fork的参数clone_flags确定的
         * 也就是说是否跟踪子进程的信息是由我们在调用的时候确定 */

        /* current这个是指当前的父进程吗?
         * unlikely原型:
         * #include <linux/compiler.h> */
 if (unlikely(current->ptrace)) {/* unlikely(x),对x两次取反,具体实现取决于gcc的版本,gcc 2.9.6是界点,其实就是取x的值 */
  trace = fork_traceflag (clone_flags);/* fork_traceflag inline在文件fork.c中,2.4.18版本没有独立出去 */
  if (trace)
   clone_flags |= CLONE_PTRACE;
 }

        /* 检查clone_flags,创建一个新的进程,拷贝由clone_flags指定的信息,但新进程不运行 */

 p = copy_process(clone_flags, stack_start, regs, stack_size, parent_tidptr, child_tidptr);

        /*
  * Do this prior waking up the new thread - the thread pointer
  * might get invalid after that point, if the thread exits quickly.
  */
 pid = IS_ERR(p) ? PTR_ERR(p) : p->pid;

        /* 进程复制成功 */
 if (!IS_ERR(p)) {
  struct completion vfork;

  if (clone_flags & CLONE_VFORK) {
   p->vfork_done = &vfork;
   init_completion(&vfork);
  }

  if ((p->ptrace & PT_PTRACED) || (clone_flags & CLONE_STOPPED)) {
   /*
    * We'll start up with an immediate SIGSTOP.
    */
   sigaddset(&p->pending.signal, SIGSTOP);
   set_tsk_thread_flag(p, TIF_SIGPENDING);
  }

  if (!(clone_flags & CLONE_STOPPED)) {
   /*
    * Do the wakeup last. On SMP we treat fork() and
    * CLONE_VM separately, because fork() has already
    * created cache footprint on this CPU (due to
    * copying the pagetables), hence migration would
    * probably be costy. Threads on the other hand
    * have less traction to the current CPU, and if
    * there's an imbalance then the scheduler can
    * migrate this fresh thread now, before it
    * accumulates a larger cache footprint:
    */
   /* 唤醒新fork的进程 */
   if (clone_flags & CLONE_VM)
    wake_up_forked_thread(p);
   else
    wake_up_forked_process(p);
  } else {
   int cpu = get_cpu();

   p->state = TASK_STOPPED;
   if (cpu_is_offline(task_cpu(p)))
    set_task_cpu(p, cpu);

   put_cpu();
  }
  ++total_forks;

  if (unlikely (trace)) {
   current->ptrace_message = pid;
   ptrace_notify ((trace << 8) | SIGTRAP);
  }

  if (clone_flags & CLONE_VFORK) {
   wait_for_completion(&vfork);
   if (unlikely (current->ptrace & PT_TRACE_VFORK_DONE))
    ptrace_notify ((PTRACE_EVENT_VFORK_DONE << 8) | SIGTRAP);
  } else
   /*
    * Let the child process run first, to avoid most of the
    * COW overhead when the child exec()s afterwards.
    */
   /* 让fork的子进程先运行 */
   set_need_resched();
 }
 return pid;
}

内容概要:本文介绍了一个基于冠豪猪优化算法(CPO)的无人机三维路径规划项目,利用Python实现了在复杂三维环境中为无人机规划安全、高效、低能耗飞行路径的完整解决方案。项目涵盖空间环境建模、无人机动力学约束、路径编码、多目标代价函数设计以及CPO算法的心实现。通过体素网格建模、动态障碍物处理、路径平滑技术和多约束融合机制,系统能够在高维、密集障碍环境下快速搜索出满足飞行可行性、安全性与能效最优的路径,并支持在线重规划以适应动态环境变化。文中还提供了关键模块的代码示例,包括环境建模、路径评估和CPO优化流程。; 适合人群:具备一定Python编程基础和优化算法基础知识,从事无人机、智能机器人、路径规划或智能优化算法研究的相关科研人员与工程技术人员,尤其适合研究生及有一定工作经验的研发工程师。; 使用场景及目标:①应用于复杂三维环境下的无人机自主导航与避障;②研究智能优化算法(如CPO)在路径规划中的实际部署与性能优化;③实现多目标(路径最短、能耗最低、安全性最高)耦合条件下的工程化路径求解;④构建可扩展的智能无人系统决策框架。; 阅建议:建议结合文中模型架构与代码示例进行实践运行,重点关注目标函数设计、CPO算法改进策略与约束处理机制,宜在仿真环境中测试不同场景以深入理解算法行为与系统鲁棒性。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值