我有代码:
int a = 0;
if (fork() == 0) {
a = a + 1;
printf("%d \n", a);
} else {
a = a - 1;
printf("%d \n", a);
}
我想知道这段代码是否将始终为两张照片打印不同的值?
或者如果在子进程将加1之后,我们将进行上下文切换,那么父进程将减负1。在这种情况下,我们将获得相同的值。问题是我不确定变量'a'是否重复,并且每个进程都将具有不同的副本(然后我们将始终获得不同的值)或被共享(然后我提到的情况可能导致相同的结果)值要打印两次)?
非常感谢!
答案 0 :(得分:2)
分叉的子代不会与其父代共享其地址空间。它得到了一个副本,尽管作为一种优化,该副本可能是一个懒惰的写时复制副本,这就是Linux所做的。
在Linux上,分叉的子进程最初将与其父进程共享其地址空间,但是如果它尝试在任何地方写入,则(假设写入尝试不是分段错误),Linux将把该写入重定向到原始副本页面。
答案 1 :(得分:2)
fork()
通过复制调用过程来创建子过程。
调用fork()
的进程是父进程,而新创建的进程是子进程。子进程和父进程在单独的内存空间中运行。但是在fork()
时,两个存储空间都具有相同的内容。
有一个名为写时复制的概念,它是对页表进行设置的一种优化,以便父级和子级进程开始共享所有相同的内存,并且仅共享在需要时,将复制任一进程写入的页面。这意味着父进程和子进程都共享同一数据的副本,并且一旦它们中的任何一个进行写操作,就会进行复制,并且一个进程的内存中的任何更改在另一个进程中都不可见。
在您的程序中-
是的,父进程和子进程都共享变量a
的副本,直到由任一进程写入变量a
,然后创建副本。任一进程(父/子)对变量a
进行的任何值更改都将保存在其自己的price
副本中,而其他进程看不到该更改。
选中此项-Copy-on-write。