Creating a Process
It is apparent that there must be some mechanism by which the system can create a new process. With the exception of some special initial processes generated by the kernel during bootstrapping (e.g., init ), all processes in a Linux environment are created by a fork system call, shown in Table 1.3. The initiating process is termed the parent , and the newly generated process, the child .
Table 1.3. Summary of the fork System Call.
Include File(s) |
|
Manual Section |
2 |
|
Summary [*] |
pid_t fork ( void ); |
|||
Return |
Success |
Failure |
Sets errno |
|
0 in child, child process ID in the parent |
-1 |
Yes |
[*] The include file usually contains the definition of pid_t . However, in some environments the actual definition will reside in . Fortunately, in these environments the contains an include statement for the alternate definition location, and all remains transparent to the casual user . The include file contains the declaration for the fork system call.
The fork system call does not take an argument. If the fork system call fails, it returns a -1 and sets the value in errno to indicate one of the error conditions shown in Table 1.4.
Table 1.4. fork Error Messages. [6]
# |
Constant |
perror Message |
Explanation |
---|---|---|---|
11 |
EAGAIN |
Resource temporarily unavailable |
The operating system was unable to allocate sufficient memory to copy the parent's page table information and allocate a task structure for the child. |
12 |
ENOMEM |
Cannot allocate memory |
Insufficient swap space available to generate another process. |
[6] If the library function/system call sets errno and can fail in multiple ways, an error message table will follow the summary table. This table will contain the error number (#), the equivalent defined constant, the message generated by a call to perror , and a brief explanation of the message in the current context.
Otherwise, when successful, fork returns the process ID (a unique integer value) of the child process to the parent process, and it returns a 0 to the child process. By checking the return value from fork , a process can easily determine if it is a parent or child process. A parent process may generate multiple child processes, but each child process has only one parent. Figure 1.12 shows a typical parent/child process relationship.
Figure 1.12. The parent/child process relationship.
As shown, process P1 gives rise to three child processes: C1, C2, and C3. Child process C1 in turn generates another child process (C4). As soon as a child process generates a child process of its own, it becomes a parent process.
When a fork system call is made, the operating system generates a copy of the parent process, which becomes the child process. The operating system passes to the child process most of the parent's system information (e.g., open file descriptors, environment information). However, some information is unique to the child process:
- The child has its own process ID (PID).
- The child will have a different parent process ID (PPID) than its parent.
- System-imposed process limits (amount of CPU time the process is allotted) are reset.
- All record locks on files are reset.
- The action to be taken when receiving signals is different.
A program that uses the fork system call is shown in Program 1.5.
Program 1.5 Generating a child process.
File : p1.5.cxx /* First example of a fork system call (no error check) */ #include + #include #include using namespace std; int main( ) { 10 cout << "Hello "; fork( ); cout << "bye "; return 0; }
The output of the program is listed in Figure 1.13.
Figure 1.13 Output of Program 1.5.
linux$ p1.5 Hello bye bye
Notice that the statement cout << "bye "; only occurs once in the program at line 12, but the run of the program produces the word " bye " twiceonce by the parent process and once by the child process. Once the fork system call at line 11 is executed there are two processes each of which executes the remaining program statements. A more detailed description of the fork system call and its uses can be found in Chapter 3, "Using Processes."