我对下面复制粘贴的程序有疑问。我在这里解释我对程序的理解:在这个程序中,父程序创建一个子程序并等待它完成。然后,孩子创建一个线程并等待它完成。因此,最后,变量“值”在子进程中将具有值“5”,在父进程中将具有“0”,因为实际上存在两个变量“ value <的副本” / strong>'一个在父母和另一个在孩子中(因为fork基本上将父母的地址空间复制到孩子)。但是,父和子中变量“值”的地址结果相同。我不明白怎么做。如果有人能解释这种行为,我将不胜感激。
#include <stdio.h>
#include <pthread.h>
int value = 0;
void *runner( void *param );
int main ()
{
int pid ;
pthread_t tid;
pthread_attr_t attr;
pid = fork();
if( pid == 0 ) /* child */
{
pthread_attr_init( &attr );
pthread_create( &tid, &attr, runner, NULL );
pthread_join(tid, NULL);
printf( "CHILD: value = %d, address = %p\n", value, &value );
}
else if( pid > 0 ) /* Parent */
{
wait(NULL);
printf( "PARENT: value = %d, address = %p\n", value, &value );
}
}
void *runner( void *param )
{
value = 5;
pthread_exit(0);
}
答案 0 :(得分:3)
现代操作系统为每个进程提供虚拟地址空间,因此一致的地址并不意味着这两个变量存储在物理内存的同一目的地上。
此外,大多数操作系统在分叉时都使用写时复制技术。这意味着父进程的部分地址空间不会复制到子进程的地址空间,直到子进程尝试更改它们为止。
答案 1 :(得分:1)
台式机CPU和许多嵌入式CPU都有称为内存管理单元(MMU)的东西。 MMU从虚拟地址转换为物理地址,因此每个进程在其自己的虚拟地址空间上运行,与其他进程分开。
MMU允许操作系统使用一些重要的技术,如按需分页,以及上述过程之间的分离。
fork()
的有效实现需要使用MMU:正如您刚刚发现的那样,父进程和子进程使用相同的虚拟地址,但在不同的虚拟地址空间中,因此通常(忽略内存映射文件)和共享内存)映射到不同的物理地址。