Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/c/62.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C fork()系统调用中的混淆_C_Linux_Fork_System - Fatal编程技术网

C fork()系统调用中的混淆

C fork()系统调用中的混淆,c,linux,fork,system,C,Linux,Fork,System,我使用fork()创建了一个父进程和一个子进程,它们共享一个名为“ptr”的内存地址。但由于一个程序的一个输出,我感到困惑: 1) ptr地址:123456 注意:父进程和子进程的地址相同,因此如果一个进程更改了此地址,则应该反映出另一个进程的地址也相同 2) 家长:*ptr=44 3) 儿童:*ptr=33 4) 打印值: 父项仍保留旧值:printf(“ptr=%d”,*ptr);//输出:仍然是44,exp是33 Child打印33,即预期值。printf(“ptr=%d”,*ptr)//

我使用fork()创建了一个父进程和一个子进程,它们共享一个名为“ptr”的内存地址。但由于一个程序的一个输出,我感到困惑:

1) ptr地址:123456 注意:父进程和子进程的地址相同,因此如果一个进程更改了此地址,则应该反映出另一个进程的地址也相同

2) 家长:*ptr=44

3) 儿童:*ptr=33

4) 打印值: 父项仍保留旧值:printf(“ptr=%d”,*ptr);//输出:仍然是44,exp是33 Child打印33,即预期值。printf(“ptr=%d”,*ptr)//印33张好的

问题1)有人能告诉我,这些值有什么不同吗?尽管父级和子级的指针地址都相同

问题2)我正在开发一个内存泄漏工具,该工具提供双重释放错误,因为它看到父级和子级释放相同的地址。然而,正如我们所看到的,这不是双重自由的情况。如何解决这个问题?工具为父级和子级看到的内存地址是否相同

请看下面的代码片段:

#include <sys/types.h>
#include <unistd.h>
#include <cstdlib>
int main()
{
 int pid, *ptr
 ptr=(int*)malloc(sizeof(int));
 *ptr=33; // Parent keeps the data as 33, before forking.

 if(pid==0){*ptr=44;} // Child modifies data, which is ignored by parent

 // Now we print the memory address and the value both by child and parent
  if(pid==0)
  {
    printf("Child data: %u\n",*ptr);
    printf("Child address: %u\n",ptr);
  }
  if(pid>0)
  {
    printf("Parent data: %u\n",*ptr);
    printf("Parent address: %u\n",ptr);
  }
}
#包括
#包括
#包括
int main()
{
整型pid,*ptr
ptr=(int*)malloc(sizeof(int));
*ptr=33;//父对象在分叉之前将数据保留为33。
如果(pid==0){*ptr=44;}//子级修改数据,父级将忽略该数据
//现在我们按子级和父级打印内存地址和值
如果(pid==0)
{
printf(“子数据:%u\n”,*ptr);
printf(“子地址:%u\n”,ptr);
}
如果(pid>0)
{
printf(“父数据:%u\n”,*ptr);
printf(“父地址:%u\n”,ptr);
}
}
输出: 儿童数据:44 子女地址:123456

父数据:33(为什么仍然是旧值?) 父地址:123456(为什么地址相同但数据不同于子地址?)

问题1)有人能告诉我这些值有什么不同吗?尽管父级和子级的指针地址都相同? 这就是全部的想法。他们可能有相同的地址,但这些地址是相同的。每个进程都有自己的地址空间。
fork()
所做的是创建一个新进程,并使其虚拟内存布局看起来像父进程

请参阅和类似主题,以获取有关其工作原理的一些说明

--(下面是长篇大论)--

fork()
上通常发生的情况是,父级和子级的页表都设置为将页标记为只读。当写入指令发生在某个位置时,内核会得到一个错误的内存,CPU会在错误的内存访问时生成这个错误。内核将为被捕获的进程分配新内存,通过操作其页表将其映射到正确的地址,将旧的缓冲区复制到新分配的缓冲区,并让写入继续。这就是所谓的。这使得初始fork很快,并且可以降低两个进程中都没有写入的页面的内存消耗

上一段只是对fork编程模型的优化。他们说早期的Unix没有这样做——它对整个过程进行了完整的内存拷贝。我还听说Cygwin的
fork()
有完整的副本

但是虚拟地址与内存的物理地址无关。CPU将其用作页表的“键”,页表定义实际内存的位置。页面表也可能会说页面无效,在这种情况下,内核有机会进行“修复”(执行写时复制、从交换空间调用页面等),或者在指针访问合法无效的情况下终止进程

问题1)有人能告诉我这些值有什么不同吗?尽管父级和子级的指针地址都相同? 这就是全部的想法。他们可能有相同的地址,但这些地址是相同的。每个进程都有自己的地址空间。
fork()
所做的是创建一个新进程,并使其虚拟内存布局看起来像父进程

请参阅和类似主题,以获取有关其工作原理的一些说明

--(下面是长篇大论)--

fork()
上通常发生的情况是,父级和子级的页表都设置为将页标记为只读。当写入指令发生在某个位置时,内核会得到一个错误的内存,CPU会在错误的内存访问时生成这个错误。内核将为被捕获的进程分配新内存,通过操作其页表将其映射到正确的地址,将旧的缓冲区复制到新分配的缓冲区,并让写入继续。这就是所谓的。这使得初始fork很快,并且可以降低两个进程中都没有写入的页面的内存消耗

上一段只是对fork编程模型的优化。他们说早期的Unix没有这样做——它对整个过程进行了完整的内存拷贝。我还听说Cygwin的
fork()
有完整的副本


但是虚拟地址与内存的物理地址无关。CPU将其用作页表的“键”,页表定义实际内存的位置。页面表也可能会说页面无效,在这种情况下,内核有机会进行“修复”(执行写时复制、从交换空间调用页面等)或者在指针访问合法无效的情况下终止进程。

您误解了内存在类Unix系统中的工作原理:父级和子级的内存是独立的。如果您想让它们通信,可以设置IPC。

您误解了内存在类Unix系统中的工作原理:父级和子级的内存是独立的。如果您想让它们通信,您可以设置IPC。即使您认为内存是一个包含单个地址的大缓冲区,它还有更多的功能

上述观点对于物理内存来说是正确的,但现代处理器包括MMU芯片(内存管理)
if(pid==0){*ptr=44;} // Child modifies data, which is ignored by parent