MCPcopy Index your code
hub / github.com/python/cpython / ChildProcessMonitor

Class ChildProcessMonitor

Lib/profiling/sampling/_child_monitor.py:55–279  ·  view source on GitHub ↗

Monitors a target process for child processes and spawns profilers for them. Use as a context manager: with ChildProcessMonitor(pid, cli_args, output_pattern) as monitor: # monitoring runs here monitor.wait_for_profilers() # optional: wait before cleanup

Source from the content-addressed store, hash-verified

53
54
55class ChildProcessMonitor:
56 """
57 Monitors a target process for child processes and spawns profilers for them.
58
59 Use as a context manager:
60 with ChildProcessMonitor(pid, cli_args, output_pattern) as monitor:
61 # monitoring runs here
62 monitor.wait_for_profilers() # optional: wait before cleanup
63 # cleanup happens automatically
64 """
65
66 def __init__(self, pid, cli_args, output_pattern):
67 """
68 Initialize the child process monitor.
69
70 Args:
71 pid: Parent process ID to monitor
72 cli_args: CLI arguments to pass to child profilers
73 output_pattern: Pattern for output files (format string with {pid})
74 """
75 self.parent_pid = pid
76 self.cli_args = cli_args
77 self.output_pattern = output_pattern
78
79 self._known_children = set()
80 self._spawned_profilers = []
81 self._lock = threading.Lock()
82 self._stop_event = threading.Event()
83 self._monitor_thread = None
84 self._poll_count = 0
85
86 def __enter__(self):
87 self._monitor_thread = threading.Thread(
88 target=self._monitor_loop,
89 daemon=True,
90 name=f"child-monitor-{self.parent_pid}",
91 )
92 self._monitor_thread.start()
93 return self
94
95 def __exit__(self, exc_type, exc_val, exc_tb):
96 self._stop_event.set()
97 if self._monitor_thread is not None:
98 self._monitor_thread.join(timeout=2.0)
99 if self._monitor_thread.is_alive():
100 print(
101 "Warning: Monitor thread did not stop cleanly",
102 file=sys.stderr,
103 )
104
105 # Wait for child profilers to complete naturally
106 self.wait_for_profilers()
107
108 # Terminate any remaining profilers
109 with self._lock:
110 profilers_to_cleanup = list(self._spawned_profilers)
111 self._spawned_profilers.clear()
112

Calls

no outgoing calls

Used in the wild real call sites across dependent graphs

searching dependent graphs…