@@ -191,6 +191,11 @@ production systems. The target process requires no modification and need not
191191be restarted. The profiler attaches, collects samples for the specified
192192duration, then detaches and produces output.
193193
194+ ::
195+
196+ python -m profiling.sampling attach --live 12345
197+ python -m profiling.sampling attach --flamegraph -d 30 -o profile.html 12345
198+
194199On most systems, attaching to another process requires appropriate permissions.
195200See :ref: `profiling-permissions ` for platform-specific requirements.
196201
@@ -529,6 +534,25 @@ I/O-bound or waiting. The function spends most of its time waiting for network,
529534disk, locks, or sleep. CPU optimization won't help here; consider async I/O,
530535connection pooling, or reducing wait time instead.
531536
537+ .. code-block :: python
538+
539+ import time
540+
541+ def do_sleep ():
542+ time.sleep(2 )
543+
544+ def do_compute ():
545+ sum (i** 2 for i in range (1000000 ))
546+
547+ if __name__ == " __main__" :
548+ do_sleep()
549+ do_compute()
550+
551+ ::
552+
553+ python -m profiling.sampling run --mode=wall script.py # do_sleep ~98%, do_compute ~1%
554+ python -m profiling.sampling run --mode=cpu script.py # do_sleep absent, do_compute dominates
555+
532556
533557GIL mode
534558--------
@@ -553,6 +577,29 @@ GIL?" and "why are my other threads starving?" It can also be useful in
553577single-threaded programs to distinguish Python execution time from time spent
554578in C extensions or I/O.
555579
580+ .. code-block :: python
581+
582+ import hashlib
583+
584+ def hash_work ():
585+ # C extension - releases GIL during computation
586+ for _ in range (200 ):
587+ hashlib.sha256(b " data" * 250000 ).hexdigest()
588+
589+ def python_work ():
590+ # Pure Python - holds GIL during computation
591+ for _ in range (3 ):
592+ sum (i** 2 for i in range (1000000 ))
593+
594+ if __name__ == " __main__" :
595+ hash_work()
596+ python_work()
597+
598+ ::
599+
600+ python -m profiling.sampling run --mode=cpu script.py # hash_work ~42%, python_work ~38%
601+ python -m profiling.sampling run --mode=gil script.py # hash_work ~5%, python_work ~60%
602+
556603
557604Exception mode
558605--------------
@@ -952,6 +999,25 @@ stack often shows event loop internals rather than the logical flow of your
952999coroutines. Async-aware mode addresses this by tracking which task is running
9531000and presenting stacks that reflect the ``await `` chain.
9541001
1002+ .. code-block :: python
1003+
1004+ import asyncio
1005+
1006+ async def fetch (url ):
1007+ await asyncio.sleep(0.1 )
1008+ return url
1009+
1010+ async def main ():
1011+ for _ in range (50 ):
1012+ await asyncio.gather(fetch(" a" ), fetch(" b" ), fetch(" c" ))
1013+
1014+ if __name__ == " __main__" :
1015+ asyncio.run(main())
1016+
1017+ ::
1018+
1019+ python -m profiling.sampling run --async-aware --flamegraph -o out.html script.py
1020+
9551021.. note ::
9561022
9571023 Async-aware profiling requires the target process to have the :mod: `asyncio `
0 commit comments