liveBook · Manning

Workflow

As explained in Grokking Concurrency

A process is an operating-system-managed instance of a running program with its own execution context and resources.

A parked car can make a trip, but only once someone starts and drives it. A program is similar: its instructions sit on disk until the operating system runs them. That running instance is a process. The operating system supplies and manages the resources it needs, rather than leaving the program to own the computer outright. section 4.2

A process has an execution context that identifies what it is running and what it can use:

  • An address space holds the memory it can access, including its variables. section 4.3
  • An executable supplies its instructions, and a process ID (PID) identifies the running instance. section 4.3
  • Resource information tracks such things as open files and network connections. section 4.3

Separate processes have separate address spaces. This lets the operating system isolate their work and allocate resources to each one; a child process cannot directly read another process’s data. Isolation has a cost: starting and managing a process is relatively heavy, and exchanging data between processes requires a communication mechanism. Threads within one process share its address space and generally cost less to create, but sharing resources calls for synchronization. section 4.2 section 4.7

Three independent children

A Python parent can start three child processes with multiprocessing.Process(target=run_child).start(). Each child runs the target function and prints its own PID and its parent’s PID. Their execution is independent; starting several processes makes concurrent work possible, but does not by itself guarantee that the hardware runs them in parallel. section 4.5 section 6.12

# Chapter 4/child_processes.py
import os
from multiprocessing import Process

def run_child() -> None:
    print("Child: I am the child process")
    print(f"Child: Child’s PID: {os.getpid()}")
    print(f"Child: Parent’s PID: {os.getppid()}")
        
def start_parent(num_children: int) -> None:
    print("Parent : I am the parent process")
    print(f"Parent : Parent’s PID: {os.getpid()}")
    for i in range(num_children):
        print(f"Starting Process {i}")
        Process(target=run_child).start()        #1
                
if __name__ == "__main__":
    num_children = 3
    start_parent(num_children)

The Python listing shows the parent starting three processes and using PIDs to distinguish their execution. section 4.5

How Grokking Concurrency covers it

How deep it goes
Explains address spaces, PIDs, execution contexts, spawning, and overhead, while deferring process communication mechanisms.
Examples
Uses a parked-car analogy and a Python parent that starts three child processes and prints their PIDs.
What it assumes
Begins with the distinction between a stored program and a running one before introducing operating-system terminology.
What you can do after
Apply it via Python multiprocessing.Process to start independent child processes and identify them by PID.
How it connects
Connects processes to threads, address spaces, interprocess communication, and operating-system multitasking.

Also explained in

Compare how 7 books explain workflow →

Related concepts

This explainer was generated by Manning's knowledge graph from the text of Grokking Concurrency. The section links point to the parts of the book it draws on.