J. T.
J. T.

Reputation: 1

Why Set Different Variables to Different Processes after fork()?

I ran into a code that looks like this

int main(void){
  pid_t pid;
  char sharedVariable='P';
  char *ptrSharedVariable=&sharedVariable;
           
  pid = fork()
  if(pid==0) {
     sharedVariable = 'C';
     print("Child Process\n");
     printf("Address is %p\n", ptrSharedVariable);
     printf("char value is %c\n", sharedVariable);
     sleep(5);
  } else {
     sleep(5);
     print("Parent Process\n");
     printf("Address is %p\n", ptrSharedVariable);
     printf("char value is %c\n", sharedVariable);
  }

By what I learned on stack overflow, I can tell that the char value of the parent and child process will be different. The child's value is 'C' and the parent's is 'P'. I also can tell that the address in both parent and child should be the same, which is the address to 'sharedVariable'(&sharedVariable).

However here are my question.

  1. What is the point of assigning different char values to different processses? Because for one thing, since we can already identify each process by pid==0 or >0, wouldn't this step be a redundancy? Another reason is I don't see a point in differentiating two processes that do the same job, can't they work without letting the programmers tell them apart?
  2. Why let the addresses of parent and child stay the same? I can suggest that since they are assumed to proceed on similar tasks, it would be convenient to do so, because then we can just copy and paste code. I am hesitant and want to make sure.
  3. if I replaced fork() with vfork(), would the result of the parent's char value then be 'C'?

Thanks a million in advance.

Upvotes: 0

Views: 315

Answers (1)

RKou
RKou

Reputation: 5221

This question has been answered several times. For example here.

Even though I may repeat what has been already written in several answers, here are some precisions for your 3 points:

  1. The naming of the char variable (sharedVariable) in the code that you shared is confusing because the variable is not shared between a parent process and a child process. The address space of the child is a copy of the address space of the parent. So, here there are two processes (father and child) running concurrently with their own stack where the above variable is located (one in the parent's stack and the other in the child's stack).
  2. The address space of a process is virtual. In each process you will see the same virtual addresses but they run with their proper code and data (i.e. they "points" on different physical memory locations). Optimizations are done in the kernel to share as most resources as possible until they are modified by one of the processes (e.g. Copy On Write principle) but this is transparent from the user space programmer's point of view.
  3. If you use vfork(), the variables are shared because the address spaces are shared between the parent and the child. You don't have a copy as it is done for fork(). The resulting child process is like a co-routine (it is lighter than a thread as even the stack is shared!). It is why the parent process is suspended until the child either exits or executes a new program. The manual warns about the risks of such an operation. Its goal is to execute a process immediately (fast fork()/exec() procedures). It is not dedicated to long living child processes as any call to the GLIBC or any other library service may either fail or trigger corruptions in the parent process. vfork() is a direct call to the system without any added value from the GLIBC. In the case of fork(), the user space libraries do lots of "housekeeping" to make the libraries usable in both parent and child processes (GLIBC's wrapper of fork() and pthread_atfork() callbacks). In the case of vfork(), this "housekeeping" is not done because the child process is supposed to be directly overwritten by another program through an execve() call. This is also the reason why a child spawn through vfork() must not call exit() but _exit() because the child would run any registered atexit() callbacks of the father process which could lead to unexpected crashes in both the child and the father processes.

Upvotes: 0

Related Questions