C 有什么公式可以知道fork()是如何对当前进程进行近乎完美的复制的吗? #包括 main() { int i,n=1; 对于(i=0;i

C 有什么公式可以知道fork()是如何对当前进程进行近乎完美的复制的吗? #包括 main() { int i,n=1; 对于(i=0;i,c,fork,C,Fork,fork()始终是当前进程的完美副本——唯一的区别是进程ID) 事实上,在大多数现代操作系统中,紧随fork()之后的两个进程共享完全相同的内存块。只有当新进程写入该内存时(在一种称为“写时复制”的操作模式下),操作系统才会创建新的拷贝--如果两个进程都没有改变内存,那么它们可以继续共享该内存块,从而节省整个系统内存 但作为一名程序员,所有这些都是隐藏的。从概念上来说,你可以把它看作是一个完美的副本 该副本包括发生fork()时变量的所有值。因此,如果fork()发生在for()循环中,且i==

fork()
始终是当前进程的完美副本——唯一的区别是进程ID)

事实上,在大多数现代操作系统中,紧随
fork()
之后的两个进程共享完全相同的内存块。只有当新进程写入该内存时(在一种称为“写时复制”的操作模式下),操作系统才会创建新的拷贝--如果两个进程都没有改变内存,那么它们可以继续共享该内存块,从而节省整个系统内存

但作为一名程序员,所有这些都是隐藏的。从概念上来说,你可以把它看作是一个完美的副本

该副本包括发生
fork()
时变量的所有值。因此,如果
fork()
发生在
for()
循环中,且
i==2
,那么新进程也将通过
for()
循环,且
i==2

但是,这些进程不共享
i
。当一个进程在
fork()
之后更改
i
的值时,另一个进程的
i
不会受到影响

要了解程序的结果,请修改程序,以便知道哪一个进程正在打印每一行,以及它正在进行哪一次迭代

#include <stdio.h>
main()
{    
    int i, n=1; 

    for(i=0;i<n;i++) { 
        fork();
        printf("Hello!");
    }
}
#包括
#包括
main(){
int i,n=4;
对于(i=0;i没有一个单一的“公式”是如何实现的,因为不同的操作系统以不同的方式来实现。但是
fork()
所做的是它复制了流程。这通常涉及到一些粗略的步骤:

  • 停止当前进程
  • 创建新流程,并初始化或复制相关的内部结构
  • 复制进程内存
  • 复制资源,如打开的文件描述符等
  • 复制CPU/FPU寄存器
  • 恢复这两个过程

当你叉叉时()您创建了一个新的子进程,该子进程具有不同的虚拟内存,但最初显示在与父进程相同的物理内存中。此时,两个进程只能从内存中读取数据。如果它们要在该公共内存中写入或更改任何内容,则它们使用不同的物理内存,并对该内存具有写入属性。因此re当您使用fork()时,您的孩子最初具有与其父亲相同的i值,但每个孩子的i值都会分别改变。

是的,有一个公式:


fork()
生成一个几乎完全相同的进程副本。但是,它返回两次。一次在原始进程中(父进程,返回子进程pid),一次在子进程中(返回0)。

您不仅分叉“主”程序,还分叉子进程! 第一条:

#include <stdio.h>
# include <sys/types.h>

main() {
    int i , n=4;
    for(i=0;i<n;i++); {
        int pid = getpid();
        if(fork() == 0) {
            printf("New process forked from %d with i=%d and pid=%d", pid, i, getpid());
        }
        printf("Hello number %d from pid %d\n", i, getpid());
    }
}
因为我=

这样写下来:

m -> c1
//then
m -> c2   c1-> c1.1
m -> c3   c1-> c1.1  c2->c2.1  c1.1 -> c1.1.1

依此类推……

是的;它只是复制所有进程的内存,这取决于操作系统。幸运的是,最流行的POSIX系统都有它们的源代码,您可以准确地读取执行
fork
时发生的情况。它们是了解fork()的标准公式吗对当前流程进行近乎完美的复制@Joachim@Sudheesh我们可以阅读,你不必重复:)尽管我怀疑问题真的是“有没有一个公式可以预测Hello会被打印多少次”我会将
getpid()
转换为
int
甚至
long
(在这种情况下,更改
printf
格式说明符)在对
printf
的调用中,只是为了确保不会出现未定义的行为。如果
pid\u t
恰好比
int
更宽或更窄,此代码将断开main和默认int?啊!你们两个:不要混淆noob。这足以说明原理。如果fork()返回负值,则创建子进程失败。fork()向新创建的子进程返回零。fork()向父进程返回一个正值,即子进程的进程ID。返回的进程ID为sys/types.h中定义的pid类型。通常,进程ID为整数。此外,进程可以使用函数getpid()检索分配给此进程的进程ID。
#include#include#include#define MAX#u COUNT 200#define BUF#u SIZE 100 void main(void){pid_t pid;int i;char BUF[BUF#SIZE];fork();pid=getpid();for(i=1;i)
main
fork
         child(1)
fork                  child(2)
         fork                     child(1.1)
fork                                          child(3)
         fork                                             child(1.2)
                      fork                                             child(2.1)