开发者

Weird behavior of parent-child-child threaded program

I have a doubt regarding the program copy-pasted below. I am explaining my understanding of the program here: In this program, the parent creates a child and waits for it complete. Then, the child creates a thread and waits for it to complete. So, at the end, the variable 'value' will have the value '5' in child process and '0' in parent process since there are in fact two copies of variable 'value' one in parent and other other in child (since fork essentially copies the address space of parent to child). However, addresses of the variable 开发者_JS百科'value' in both parent and child are turning out to be the same. I don't understand how. I will be grateful if someone can explain this behaviour.

#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);
   }


Modern operating systems provide a virtual address space for each process, so a coinciding address doesn't mean that the two variables are stored at the same destination on physical memory.

Moreover, most operating systems use the copy-on-write technique when forking. This means that parts of the address space of the parent process are not copied to the child's address space until the child attempts to change them.


Desktop CPUs, and many embedded CPUs have something called a Memory Management Unit (MMU). An MMU translates from virtual addresses to physical addresses, so each process runs on its own virtual address space, separated from other processes.

An MMU allows the operating system to use some important techniques, like on-demand paging, in addition to the separation between processes mentioned above.

Efficient implementation of fork() requires the use of an MMU: as you have just discovered, the parent and child process use the same virtual addresses, but in different virtual address spaces, thus usually (ignoring memory-mapped files and shared memory) mapping to different physical addresses.

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜