Linux内核学习之进程的产生(2)

        如果看了学完前面Linux内核中进程的创建,那么至少对Linux内核中进程产生的机制有了一定的了解。下面就记录一些进程的产生的学习笔记。参考书籍和使用平台还是不变。

        1.第一个进程:第一个进程事实上就是Linux kernel本身,第一个进程是唯一一个静态创建的进程,它是在Linux kernel编写和编译的时候创建。具体看看这个进程(注意:在内核中,这个进程叫做init task/thread(pid 0),但是他不是系统起来之后你ps列出来的那个进程init(pid 1))

Code:
  1. /* arch/i386/kernel/init_task.c*/  
  2. static struct fs_struct init_fs =INIT_FS;   
  3. static struct files_struct init_files = INIT_FILES;   
  4. ………………   

可以看出来,这个进程的所有结构都是静态创建的,他们位于代码段,init_thread_union位于数据段。

        2.fork,clone,kernel_thread:系统之中的其他进程都是由其父进程派生出来的,Linux提供了两个系统调用fork和clone来实现。理论上他们都是fork,由于Linux之后引入了线程的概念,即一种轻量级的进程的概念,是由clone实现的。而他们在底层的调用都是do_fork实现的。关于fork在应用层上的实现,以前学习过了,不用这里浪费水电阐述。下面做Linux内核中系统调用的分析。

fork分析:内核的具体代码冗长不说,以后的更新也是会有变化的,直接分析原理。fork()的原理如下(附上一些内核源码):

        (1)为新进程分配一些基本的数据结构,如task_struct等。

Code:
  1. static struct task_struct *dup_task_struct(structt task_struct *orig)   
  2. {   
  3.     struct task_struct *tsk;   
  4.     struct thread_info *ti;   
  5.   
  6.     prepare_to_copy (orig);   
  7.   
  8.     tsk=alloc_tast_struct();   
  9.     if(!tsk)   
  10.         return NULL;   
  11.     ti = alloc_thread_info ( tsk );   
  12.     if(!ti){   
  13.         free_task_struct(tsk);   
  14.         return NULL;   
  15.     }   
  16.     *tsk = *orig;   
  17.     *tsk->thread_info=ti;   
  18.     setup_thread_info=ti;   
  19.        
  20.     atomic_set(&tsk->usage,2);   
  21.     atomic_set (&tsk->fs_excl,0);   
  22.     return tsk;   
  23. }  

 

        (2)共享或者拷贝父进程的资源

        (3)为子进程创建虚拟地址空间:一下代码看出,dup_mm主要实现了复制内存的工作

   

Code:
  1. static int copy_mm(unsigned long clone_flags,struct task_struct *tsk)   
  2. {   
  3.     ……   
  4.   retval = -ENOMEM;   
  5.     mm=dup_mm(tsk);   
  6.     if(!mm){   
  7.         goto fail_nomem;   
  8.     }       
  9.        
  10. good_mm:   
  11.     tsk->mm=mm;   
  12.     tsk->active_mm=mm;   
  13.     return 0;   
  14.   
  15. fail_nomem:   
  16.     return retval;   
  17. }  

        (4)为子进程设置好相关虚拟地址空间:这一部分太抽象,我觉得现在不需要理解太多…………

        (5)fork()的返回:fork()调用之后有2个返回值,父进程返回子进程的pid很好理解,下面着重理解子进程的返回。在do_fork()中,copy_process()调用完成后,如果没有出错,父进程会去唤醒子进程:

Code:
  1. if(!(clone_flags&CLONE_STOPPED)))   
  2.     wake_up_new_task(p,clone_flags);   
  3. else  
  4.     p->stats = TASK_STOPPED;   

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值