如果我有一个进程,并且我克隆它,那么PID是否相同?

use*_*033 1 linux fork pid exec

只是一个简单的问题,如果我克隆一个进程,克隆进程的PID是一样的,是吗?fork()创建一个PID不同的子进程,但其他一切都是相同的.Vfork()使用相同的PID创建子进程.Exec用于将当前正在执行的进程更改为其他进程.

我在所有这些陈述中都是正确的吗?

Bri*_*new 6

不完全的.如果您通过fork/exec或vfork/exec克隆进程,您将获得一个新的进程ID.fork()将为您提供具有新进程ID的新进程,并exec()使用新进程替换该进程,但保留进程ID.

这里:

vfork()函数与fork()的不同之处仅在于子进程可以与调用进程(父进程)共享代码和数据.如果误用vfork(),这会显着加快克隆活动,从而对父进程的完整性造成风险.


pax*_*blo 6

无论是fork()vfork()保持相同的PID虽然clone() 可以在一个场景(*一).它们是实现大致相同目的的不同方式,即创造独特的孩子.

clone()就像fork()两个进程共享很多东西,这通常用于启用线程.

vfork()clone父进程停止直到子进程退出或执行另一个程序的变体.在这些情况下它更有效,因为它不涉及复制页表等.基本上,只要子进程加载另一个程序,就可以在两个进程之间共享所有内容.

将最后一个选项与正常的写时复制进行对比,其中共享内存本身(直到其中一个进程写入它),但复制了引用该内存的页表.换句话说,vfork()甚至比写入时复制,至少对叉,接着逐即时EXEC用例高效.

但是,在大多数情况下,孩子与父母的进程ID不同.


*当你clone()有事情时,事情会变得棘手CLONE_THREAD.在那个阶段,进程仍然具有不同的标识符,但是PID的构成开始变得模糊.在最深层次上,Linux调度程序不关心进程,它会调度线程.

线程具有线程ID(TID)和线程组ID(TGID).TGID就是你得到的getpid().

没有 克隆一个线程时CLONE_THREAD,它会被赋予一个新的TID,并且它的TGID也设置为该值(即一个全新的PID).

有了 CLONE_THREAD,它给了一个新的TID,但TGID(因此报告的进程ID)保持与父级相同,因此它们实际上具有相同的PID.但是,他们可以通过获取TID来区分自己 gettid().

关于父进程ID和信号传递(包括组内线程和SIGCHLD父线程)都有相当多的诡计,所有这些都可以从clone()手册页中查看.