p { margin-bottom: 0.21cm; }
子进程和父进程的pid 一定不同吗?
一般来说,子父进程的pid 是不同的。
除了系统的原始的0 号进程,创建一个进程可以调用fork() 、vfork() 、clone() 函数。在/kernel/fork.c 的fork() 函数中有一个标志位CLONE_PID, 但这个标志位为1 时,子父进程共用一个进程号,也就是说,子进程虽然有自己的task_struct 数据结构,却使用父亲进程的pid 。但是,只有0 号进程,也就是系统中的原始进程,才允许这样来调用__clone() 。
因为存在这样的特例,在内核中我们判断是否为同一个进程,仅仅依据pid ,就有一点不安全。怎么办呢?
由于内核进程或线程,都有自己的内核堆栈,我们可以比较二者的堆栈的esp 指针,不同进程线程的esp 肯定是不同的,这种方法在2.6.24 的源码的arch/i386/kernel/process.c 的kernel_thread() 函数中有这样的一句代码:cmpl %%esp,%%esi 。但是这个方法不适合用户态的进程,因为用户态的进程不知到自己对应的内核堆栈指针,并且用户态的进程或线程的pid 一定是不同的。前面的特例,仅仅是这内核态有这种pid 相同的情况。