Separating image generation and display into different OS processes prevents Python's GIL from throttling GPU throughput
Python’s Global Interpreter Lock (GIL) prevents two threads from running Python bytecode simultaneously. In a naive implementation, a tkinter or pygame display loop sharing a thread with the GPU inference loop would serialise them. StreamDiffusion’s examples spawn separate OS processes using multiprocessing.get_context('spawn'): one process owns the CUDA context and runs the inference loop, another owns the display (tkinter/OpenCV). Data crosses the process boundary via multiprocessing.Queue. block=False on queue.put() means the inference process never stalls waiting for the display to consume frames; frames are dropped instead of blocking GPU utilisation.
Examples
ctx = get_context('spawn') # CUDA-safe on all platforms
queue = ctx.Queue()
process1 = ctx.Process(target=image_generation_process, args=(queue, ...))
process2 = ctx.Process(target=receive_images, args=(queue, ...))
process1.start(); process2.start()
Assessment
Why is get_context('spawn') preferred over get_context('fork') for CUDA workloads? What would go wrong if the CUDA context were forked rather than freshly initialised in the child process?