First, let's take a look at a very interesting piece of code extracted from advanced programming for UNIX environments. Let's take a look at some questions about the fork () function.
#include "apue.h"static void charatatime(char*);intmain(void){ pid_tpid; if((pid=fork())<0){ err_sys("fork error"); }else if(pid==0){ charatatime("output from child\n"); }else{ charatatime("output from parent\n"); } exit(0);}static voidcharatatime(char *str){ char*ptr; intc; setbuf(stdout,NULL); /*set unbuffered*/ for(ptr=str;(c=*ptr++)!=0;) putc(c,stdout);}What did this code do? In fact, it is very simple. First, a subprocess is generated using the fork () function. In fact, sub-processes can be seen as a replication of the parent process. In the code above, how can we determine whether a child process or a parent process is being executed? Now let's take a look at the return values of the fork () function.
The return value of Fork:
After fork is called, both parent and child processes start to run after fork. Of course, the Parent and Child processes do different things, but as mentioned above, child processes are a copy of the parent process and they actually share a code segment. At this time, we need to rely on the return value of Fork () to determine whether the currently running program is a parent process or a child process. The fork () function is a very interesting guy. It is called only once, but two return values are returned to the parent and child processes respectively.
In the parent process, fork () returns the ID of the child process. It is worth noting that the parent process can obtain the ID of the child process only when the fork () function is used. Otherwise, there will be no chance. Because a parent process can have multiple child processes, it is obviously difficult to obtain the process ID of a specific child process through a function. Unlike the parent process, a child process usually has only one parent process. Therefore, you can use a function called getppid () to find the ID of the parent process.
The return value of Fork () in the sub-process is 0. Why? Because 0 is usually the process number retained by the system, it is impossible for a sub-process to be 0. As shown in the code above, when pid = 0, the number of characters passed to the sub-function is "output from child"; otherwise, it is in the parent process, the passed string naturally becomes "output from parent ".
Another problem is that after fork (), the Parent and Child processes can be considered as two independent processes. So what is the first execution of the parent process? Or should we execute the sub-process first? So let's talk about the competition between processes.
Race Condition ):
Who runs the Parent and Child processes first? In fact, in general, this is unpredictable, depending on a series of other factors such as the scheduling algorithm of the kernel. We can come and see the above Code. In the charatatime function jointly called by the parent and child processes, we first use setbuf to cancel the standard I/O buffer. In this way, in the for loop below, we only need to putc once, the corresponding characters are displayed on shell. Based on the above analysis, we can predict that the two strings may not be completely output in sequence. Because inter-process switching is very likely, a string may not be completely input, and the kernel will execute the output of another string. Therefore, the result displayed in the shell may be a cross-output string. The following figure shows the result:
Obviously, the output results are unpredictable. Sometimes the output results are compared with the rule, but sometimes they are messy. This is race condition between processes ). Of course, there are many ways to solve the competition. We can solve the competition through signal and inter-process communication (IPC) waiting. Let's talk about this later!
References: Advanced Programming in the Unix environment
Look at the fork () function and its competition from a piece of code