System Calls and fork() — Study Notes
1. What is a System Call?
A system call is the interface through which a user-level program requests a service from the operating system kernel.
Why are System Calls Needed?
- User programs normally cannot directly perform privileged operations.
- The operating system provides controlled access to hardware and kernel services.
- System calls provide a bridge between user programs and the OS kernel.
- Examples include:
- Creating processes
- Performing file operations
- Accessing devices
- Communicating between processes
Basic System Call Flow
User Program
↓
System Call
↓
Kernel / Operating System
↓
Service
↓
Result returned to program
2. Major Categories of System Calls
| Category | Purpose | Examples |
|---|---|---|
| Process Control | Create, execute, terminate and control processes | fork(), exec(), wait(), exit() |
| File Management | Create, open, read, write and close files | open(), read(), write(), close() |
| Device Management | Request/release and control devices | read(), write(), ioctl() |
| Information Maintenance | Get/set process and system information | getpid(), time(), uname() |
| Communication | Exchange information between processes/systems | pipe(), socket(), send(), recv() |
| Protection | Control access and permissions | chmod(), access(), setuid() |
3. Process-Control System Calls
fork()
Creates a new child process by duplicating the calling process.
exec()
Replaces the current process image with another program.
wait()
Allows a parent process to wait for a child process to change state, commonly to terminate.
exit()
Terminates a process and returns an exit status.
4. Basic Process Terms
Process
A process is a program that is currently executing.
PID
PID stands for Process ID.
Each running process has its own process ID.
PPID
PPID stands for Parent Process ID.
It identifies the process that created the current process.
Example:
Parent PID = 1200
Child PID = 1201
Child PPID = 1200
getpid() and getppid()
getpid(); // returns current process ID
getppid(); // returns parent process ID
Example:
#include <stdio.h>
#include <unistd.h>
int main()
{
printf("PID = %d\n", getpid());
printf("PPID = %d\n", getppid());
return 0;
}
Process Address Space
A process has its own address space, which commonly contains:
Code
Data
Heap
Stack
5. fork() System Call
Definition of fork()
fork() creates a new process called the child process.
The process that calls fork() is called the parent process.
After a successful fork(), both parent and child continue execution from the point immediately after fork().
6. Header File and Syntax
#include <unistd.h>
pid_t fork(void);
unistd.h stands for the Unix standard header and contains declarations for functions such as fork() and getpid().
pid_t is the data type commonly used for storing process IDs and the return value of fork().
Example:
pid_t pid;
pid = fork();
7. Return Values of fork()
| Return Value | Process | Meaning |
|---|---|---|
0 |
Child | fork() succeeded and this is the child process |
> 0 |
Parent | fork() succeeded; the returned value is the PID of the child |
-1 |
Parent | fork() failed; no child is created |
Important Concept
One fork() call can result in two processes.
Both processes execute the statements after fork(), but the return value allows the program to distinguish between the parent and child.
pid == 0 → Child Process
pid > 0 → Parent Process
pid == -1 → fork() failed
8. Parent and Child Example
#include <stdio.h>
#include <unistd.h> // UNIX Standard
int main()
{
fork();
printf("Hello from process\n");
return 0;
}
Explanation
Initially, there is one process: the parent.
fork() creates one child process.
After fork(), both the parent and child execute:
printf("Hello from process\n");
Therefore, the message normally appears two times.
Expected Output
Hello from process
Hello from process
The exact order of the two outputs is not guaranteed because the scheduler decides which process runs first.
9. Identify Parent and Child
#include <stdio.h>
#include <unistd.h>
int main()
{
pid_t pid;
pid = fork();
if (pid == 0)
{
printf("I am the Child Process\n");
}
else if (pid > 0)
{
printf("I am the Parent Process\n");
}
else
{
printf("Fork failed\n");
}
return 0;
}
Explanation
pidstores the return value offork().- In the child process,
fork()returns0, so the child prints its message. - In the parent process,
fork()returns the child's PID, which is a positive value. - If
fork()fails, it returns-1and the failure message is printed.
10. Display Parent and Child PIDs
#include <stdio.h>
#include <unistd.h>
#include <sys/types.h>
int main()
{
pid_t pid;
pid = fork();
if (pid == 0)
{
printf("Child: PID = %d\n", getpid());
}
else if (pid > 0)
{
printf("Parent: PID = %d, Child PID = %d\n",
getpid(), pid);
}
else
{
printf("Fork failed\n");
}
return 0;
}
Explanation
fork()creates the child process.- The child receives
0fromfork()and callsgetpid()to print its own PID. - The parent receives the child's PID from
fork(). - The parent can therefore print both its own PID and the child's PID.
- The actual numeric PID values will be different on every execution.
Example Output
Parent: PID = 5000, Child PID = 5001
Child: PID = 5001
11. getpid() vs pid
This distinction is important:
getpid() in parent → Parent's own PID
getpid() in child → Child's own PID
pid in parent → Child's PID
pid in child → 0
So:
getpid()returns the current process ID.- In the parent, the variable receiving the return value of
fork()contains the child's PID. - In the child, that variable contains
0.
12. Process Diagram for fork()
Before fork()
Parent
|
fork()
/ \
/ \
Parent Child
pid > 0 pid = 0
13. Important Points About fork()
fork()creates a child process.- The child is a separate process with its own PID.
- Both parent and child continue from the statement after
fork(). - Parent receives the child's PID as the return value.
- Child receives
0as the return value. - On failure,
fork()returns-1to the parent and no child is created. - Output order after
fork()may vary because process scheduling is nondeterministic. - On Linux,
fork()uses copy-on-write, so memory pages are not immediately physically copied.
Quick Summary
fork() → Create child process
Parent → fork() returns Child PID (> 0)
Child → fork() returns 0
Failure → fork() returns -1
14. fork() with Parent and Child Identification
#include <stdio.h>
#include <unistd.h> // UNIX Standard
int main()
{
int pid;
pid = fork();
if (pid == 0)
{
printf("Child Process\n");
printf("Child PID = %d\n", getpid());
}
else if (pid > 0)
{
printf("Parent Process\n");
printf("Parent PID = %d\n", getpid());
printf("Child PID = %d\n", pid);
}
else
{
printf("Fork failed\n");
}
return 0;
}
Important Points
pid == 0 → Child process
pid > 0 → Parent process
getpid()→ returns the current process ID.pidin the parent → contains the child's PID.
15. fork() with Different Execution in Parent and Child
#include <stdio.h>
#include <unistd.h> // UNIX Standard
int main()
{
int pid;
pid = fork();
if (pid == 0)
{
printf("Child Process Started\n");
for (int i = 1; i <= 3; i++)
{
printf("Child: %d\n", i);
}
}
else if (pid > 0)
{
printf("Parent Process Started\n");
for (int i = 1; i <= 3; i++)
{
printf("Parent: %d\n", i);
}
}
else
{
printf("Fork failed\n");
}
return 0;
}
Important Point
After:
pid = fork();
there are two processes executing the code:
fork()
|
+-----+-----+
| |
Parent Child
pid > 0 pid = 0
| |
Parent loop Child loop
Parent and child execute independently, so the exact order of their output is not guaranteed.
16. Basic Linux Process Commands
ps
Shows processes associated with the current terminal.
ps
ps -e
Shows all running processes.
ps -e
echo $$
Shows the PID of the current shell.
echo $$
pidof
Shows the PID of a running program.
pidof bash
General syntax:
pidof <program-name>
17. Compile and Run a C Program
Suppose the C file is:
program.c
Compile it using GCC:
gcc program.c -o program
Run the program:
./program
When running a program containing fork(), the order of parent and child output may differ between executions.
18. Number of Processes After Multiple fork() Calls
If every process executes every fork() call:
1 fork() → 2 processes
2 fork()s → 4 processes
3 fork()s → 8 processes
General rule:
Number of processes = 2^n
where n is the number of unconditional fork() calls.
Example:
fork();
fork();
Total processes:
2² = 4
19. Quick Revision
System Call
User Program
↓
System Call
↓
Kernel
↓
Service
fork()
fork()
|
+---- Parent → return value > 0
|
+---- Child → return value = 0
Failure → -1
PID Functions
getpid(); // Current Process ID
getppid(); // Parent Process ID
Core Points
fork()creates a child process.- Parent and child both continue after
fork(). - Parent receives the child's PID.
- Child receives
0. - Each process has its own PID.
- Output order is not guaranteed.
- Linux uses copy-on-write after
fork().
One-Line Definition
fork()creates a child process, and both parent and child continue execution from the next statement.