6.2 Process ID and Parent Process ID

6.2 Process ID and Parent Process ID
Linux System Programming — Chapter 6
2
System Calls
3
Code Examples
6
Interview Questions

What You Will Learn

Every process on a Linux system has a unique numeric identifier called a PID (Process ID). Every process also knows the PID of its creator — the PPID (Parent Process ID). These two values form the backbone of the Linux process tree.

Process ID (PID) Basics

The kernel assigns a unique positive integer PID to each new process. PIDs are issued sequentially. The getpid() system call returns the PID of the calling process. It always succeeds — it never returns an error.

PID Key Facts
Property Value / Detail
Data type pid_t (positive integer, defined in <unistd.h>)
Default max PID 32,767 (tunable via /proc/sys/kernel/pid_max)
64-bit max PID Up to 2²² (~4 million) on 64-bit platforms
Wrap-around resets to 300 (not 1 — low PIDs are reserved for system daemons)
PID 1 init / systemd — ancestor of all processes
System call pid_t getpid(void) — always succeeds

Parent Process ID (PPID)

Every process (except PID 1) was created by another process — its parent. getppid() returns the PID of the calling process’s parent. If the parent dies before the child, the child is adopted by init (PID 1), so getppid() returns 1.

Linux Process Tree (simplified)
PID 1: systemd / init
(ancestor of all processes)
PID 512
bash
PPID=1
PID 620
sshd
PPID=1
PID 730
cron
PPID=1
PID 800
./myprogram
PPID=512
Orphan Process: If a parent exits before its child, the child becomes an orphan and is automatically re-parented to init (PID 1). getppid() will then return 1.

Inspecting PIDs via /proc

Linux exposes every process’s attributes through the virtual filesystem at /proc/PID/. You can read a process’s parent PID from /proc/PID/status.

# Check your shell's PID and parent PID
$ echo $$               # PID of current bash shell → e.g., 4100
$ cat /proc/4100/status | grep -E "^(Pid|PPid)"
Pid:    4100
PPid:   3990

Code Examples

Example 1: Print PID and PPID
#include <stdio.h>
#include <unistd.h>

int main(void)
{
    printf("My PID   : %d\n", getpid());
    printf("Parent PID: %d\n", getppid());

    /* Tip: Run this in a terminal.
       Your parent is the shell (bash/zsh).
       Verify: $ ps -p <PPID> */
    return 0;
}

/* Sample output:
   My PID   : 7820
   Parent PID: 7680   ← this is your bash shell */
Example 2: Parent-Child PID Relationship with fork()
#include <stdio.h>
#include <unistd.h>
#include <sys/wait.h>

int main(void)
{
    pid_t child_pid = fork();

    if (child_pid == 0) {
        /* --- CHILD PROCESS --- */
        printf("[Child]  My PID    = %d\n", getpid());
        printf("[Child]  My PPID   = %d  (parent's PID)\n", getppid());
    } else {
        /* --- PARENT PROCESS --- */
        printf("[Parent] My PID    = %d\n", getpid());
        printf("[Parent] Child PID = %d\n", child_pid);
        wait(NULL);   /* Wait for child to finish */
    }
    return 0;
}

/* Sample output:
   [Parent] My PID    = 9100
   [Parent] Child PID = 9101
   [Child]  My PID    = 9101
   [Child]  My PPID   = 9100  ← matches parent's PID */
Example 3: Build a Unique Filename Using PID

A common use of PIDs is creating temporary filenames that won’t collide with other processes.

#include <stdio.h>
#include <unistd.h>

int main(void)
{
    char tmpfile[64];

    /* Build a unique filename using our PID */
    snprintf(tmpfile, sizeof(tmpfile), "/tmp/myapp_%d.tmp", getpid());

    printf("Creating unique temp file: %s\n", tmpfile);

    FILE *fp = fopen(tmpfile, "w");
    if (fp) {
        fprintf(fp, "Process %d was here\n", getpid());
        fclose(fp);
        printf("Done. File created.\n");
        /* In real code, unlink(tmpfile) to delete when done */
    }
    return 0;
}

/* Output:
   Creating unique temp file: /tmp/myapp_9250.tmp
   Done. File created.

   Each run produces a different filename because
   each process gets a unique PID. */

Interview Preparation Questions

Q1. What is a PID and why is it useful?

A PID is a unique positive integer assigned by the kernel to each running process. It’s used to send signals (kill -9 <PID>), to build unique filenames, to look up process info in /proc/PID/, and in system calls like waitpid().

Q2. What is the default maximum PID on Linux?

32,767 by default. After reaching this limit, the kernel wraps around and starts from 300 (not 1, because low PIDs are used by system processes). On 64-bit systems, /proc/sys/kernel/pid_max can be set up to ~4 million.

Q3. What is an orphan process? What happens to it?

An orphan process is a child whose parent has already exited. Linux automatically re-parents it to init (PID 1). After re-parenting, getppid() in the child returns 1. This prevents orphaned processes from becoming zombies permanently.

Q4. What is the difference between getpid() and getppid()?

getpid() returns the PID of the calling process itself. getppid() returns the PID of the process that created (forked) the calling process. Both always succeed and never return an error.

Q5. Where can you find a process’s PPID without calling getppid()?

In /proc/PID/status — look for the “PPid:” field. You can also use: ps -o pid,ppid -p <PID> or pstree -p to visualize the entire process hierarchy.

Q6. What does fork() return in the parent vs the child?

fork() returns the child’s PID in the parent process, and returns 0 in the child process. If fork() fails (e.g., process limit reached), it returns -1 in the parent and no child is created.

Leave a Reply

Your email address will not be published. Required fields are marked *