views:

1326

answers:

5

I have this program in C++ that forks two new processes:

#include <pthread.h>
#include <iostream>
#include <unistd.h>
#include <sys/types.h>
#include <sys/wait.h>
#include <cstdlib>
using namespace std;

int shared;

void func(){
  extern int shared;
  for (int i=0; i<10;i++)
        shared++;
  cout<<"Process "<<getpid()<<", shared "
        <<shared<<", &shared "
        <<&shared<<endl;
}

int main(){
  extern int shared;
  pid_t p1,p2;
  int status;
  shared=0;
  if ((p1=fork())==0) {func();exit(0);};
  if ((p2=fork())==0) {func();exit(0);};
  for(int i=0;i<10;i++)
        shared++;
  waitpid(p1,&status,0);
  waitpid(p2,&status,0);;
  cout<<"shared variable is: "<<shared<<endl;
  cout<<"Process "<<getpid()<<", shared "
        <<shared<<", &shared "
        <<&shared<<endl;
}

The two forked processes make an increment on the shared variables and the parent process does the same. As the variable belongs to the data segment of each process, the final value is 10 because the increment is independent.

However, the memory address of the shared variables is the same, you can try compiling and watching the output of the program. How can that be explained ? I cannot understand that, I thought I knew how the fork() works, but this seems very odd..

I need an explanation on why the address is the same, although they are separate variables.

+7  A: 

The OS is using virtual memory and similar techniques to ensure that each process sees different memory cells (virtual or read) at the same addresses; only memory that's explicitly shared (e.g. via shm) is shared, all memory by default is separate among separate processes.

Alex Martelli
+4  A: 

Pointers on modern systems doesn't correspond to actual hardware memory addresses. Rather the addresses maps to a virtual space managed by the operating system. Therefore the pointer addresses for two different processes can appear to be the same when they in reality are not.

Emil H
+7  A: 

This is called "virtual address". Each process has its own address space, and each address means something different, depending on the process. fork() creates a copy, instead of sharing data (technically, they may get shared copy-on-write, but this is has the same effect as upfront copying would). IOW, the variable "shared" is not shared between processes.

Martin v. Löwis
A: 

Does this apply to pthread_mutex objects also. Say I have mutex in the parent that gets locked and unlocked in a particular function. Now the parent creates a child process. Both parent and child can call this function simultaneously (Parent not really blocked till child exits as parent is a multi-threaded program, the thread that spawns child is only one blocked). So is the mutex object state - shared between the 2 processes? If in parent, mutex was locked then child was created child gets to run first child sees the mutex in locked state as it has just inherited the mutex object as it is from parent now child unlocks mutex How is the state of this mutex in parent now - still locked (because parent never unlocked) or Unlocked because child has unlocked it.

Is it ok to call such a function that locks/unlocks global mutexes from parent and child?

A: 

yes what you have thought is right but in order to save some memory, internally the pages are shared between the parent and the child till the child executes exec system call or modifies any of the variables or the data structures.since many pages are shared between parent and child.....if the page is modified by child,then that page will copied into separate memory area and will be assigned to the child.if it is modified by parent,then that page will be copied to separate memory area and assigned to the parent

vishal