Process Management: fork, exec, wait
Understanding how Linux creates and manages processes is essential for any systems programmer. At the core of process management are the fork, exec, and wait system calls. These calls allow you to launch new programs, manage parent-child relationships, and synchronize execution between processes. When you use fork, your program creates a new process—called the child—which is a nearly identical copy of the parent process. This forms a parent-child relationship, where both processes continue executing independently, but often need to coordinate their actions. To replace the child’s code with a new program, you use the exec family of calls. The parent, meanwhile, can use wait to pause its execution until the child finishes, ensuring proper synchronization and resource cleanup.
process_management_example.c
12345678910111213141516171819202122232425262728293031#include <stdio.h> #include <stdlib.h> #include <unistd.h> #include <sys/wait.h> int main() { pid_t pid = fork(); if (pid < 0) { perror("fork failed"); exit(EXIT_FAILURE); } else if (pid == 0) { // Child process printf("Child: My PID is %d. Executing 'ls -l'.\n", getpid()); execl("/bin/ls", "ls", "-l", (char *)NULL); // If exec fails perror("execl failed"); exit(EXIT_FAILURE); } else { // Parent process printf("Parent: My PID is %d. Waiting for child PID %d.\n", getpid(), pid); int status; waitpid(pid, &status, 0); if (WIFEXITED(status)) { printf("Parent: Child exited with status %d.\n", WEXITSTATUS(status)); } else { printf("Parent: Child did not exit normally.\n"); } } return 0; }
When you call fork, it returns the child’s process ID (PID) to the parent and zero to the child. This allows each process to determine its role after the fork. In the example above, the child process uses execl—a variant of the exec family—to replace its code with the ls -l command. If exec succeeds, the child’s original code is replaced and execution continues in the new program; if it fails, the child prints an error and exits. Meanwhile, the parent process receives the child’s PID and can use waitpid (or wait) to pause until the child finishes. This synchronization is crucial: without it, the parent might finish before the child, potentially leaving resources uncollected or creating unpredictable behavior. The use of process IDs, return values from fork, and explicit synchronization via wait are fundamental for robust process management in Linux.
Danke für Ihr Feedback!
Fragen Sie AI
Fragen Sie AI
Fragen Sie alles oder probieren Sie eine der vorgeschlagenen Fragen, um unser Gespräch zu beginnen
Großartig!
Completion Rate verbessert auf 7.69
Process Management: fork, exec, wait
Swipe um das Menü anzuzeigen
Understanding how Linux creates and manages processes is essential for any systems programmer. At the core of process management are the fork, exec, and wait system calls. These calls allow you to launch new programs, manage parent-child relationships, and synchronize execution between processes. When you use fork, your program creates a new process—called the child—which is a nearly identical copy of the parent process. This forms a parent-child relationship, where both processes continue executing independently, but often need to coordinate their actions. To replace the child’s code with a new program, you use the exec family of calls. The parent, meanwhile, can use wait to pause its execution until the child finishes, ensuring proper synchronization and resource cleanup.
process_management_example.c
12345678910111213141516171819202122232425262728293031#include <stdio.h> #include <stdlib.h> #include <unistd.h> #include <sys/wait.h> int main() { pid_t pid = fork(); if (pid < 0) { perror("fork failed"); exit(EXIT_FAILURE); } else if (pid == 0) { // Child process printf("Child: My PID is %d. Executing 'ls -l'.\n", getpid()); execl("/bin/ls", "ls", "-l", (char *)NULL); // If exec fails perror("execl failed"); exit(EXIT_FAILURE); } else { // Parent process printf("Parent: My PID is %d. Waiting for child PID %d.\n", getpid(), pid); int status; waitpid(pid, &status, 0); if (WIFEXITED(status)) { printf("Parent: Child exited with status %d.\n", WEXITSTATUS(status)); } else { printf("Parent: Child did not exit normally.\n"); } } return 0; }
When you call fork, it returns the child’s process ID (PID) to the parent and zero to the child. This allows each process to determine its role after the fork. In the example above, the child process uses execl—a variant of the exec family—to replace its code with the ls -l command. If exec succeeds, the child’s original code is replaced and execution continues in the new program; if it fails, the child prints an error and exits. Meanwhile, the parent process receives the child’s PID and can use waitpid (or wait) to pause until the child finishes. This synchronization is crucial: without it, the parent might finish before the child, potentially leaving resources uncollected or creating unpredictable behavior. The use of process IDs, return values from fork, and explicit synchronization via wait are fundamental for robust process management in Linux.
Danke für Ihr Feedback!