关于Linux中的线程,Linux采用了一种“偷懒”的方法,Linux没有专门的线程对象,当需要建立一个线程时,实际上内核创建的是一个进程对象,也就是task_struct,只不过这个进程对象和父进程共享了大量资源,有时也称为轻权进程(LightWeight Process)。Linux建立进程和线程的接口也一致,比如都是fork(),而通过不同的参数来指定要建立的是进程还是线程调用fork()函数将返回两次,一次是在父进程中,一次是在子进程中,这一定会让大都数人疑惑。其实fork()就是把当前的进程对象task_struct复制一份,这样在进程队列中就多了一个进程对象,由于两个进程相同,所以调度器调度到父进程时,返回一次,调度到子进程时,返回一次。

那么fork()调用一次返回两次的原理是什么呢?这可通过do_fork()所调用的函数copy_thread()来回答。应用程序通过fork()系统调用进入内核空间,其内核态堆栈上保存着该进程的进程上下文(即该进程的各个寄存器),通过复制父进程的内核态堆栈上的进程上下文,同时将eax置为0(如linux 1.2*childregs = *regs;  childregs->eax = 0;),而父进程通过do_fork()的返回值(return last_pid)来得到fork()的返回值。

 

Logo

更多推荐