import sys import threading import time from contextlib import contextmanager # we need a lock, so that other threads don't snatch control # while we have set a temporary parent stdout_lock = threading.Lock() @contextmanager def set_stdout_parent(parent): """a context manager for setting a particular parent for sys.stdout the parent determines the destination cell of output """ save_parent = sys.stdout.parent_header with stdout_lock: sys.stdout.parent_header = parent try: yield finally: # the flush is important, because that's when the parent_header actually has its effect sys.stdout.flush() sys.stdout.parent_header = save_parent tic = time.time() class counterThread(threading.Thread): def run(self): # record the parent when the thread starts thread_parent = sys.stdout.parent_header for i in range(3): time.sleep(2) # then ensure that the parent is the same as when the thread started # every time we print with set_stdout_parent(thread_parent): print i, "%.2f" % (time.time() - tic) for i in range(3): counterThread().start() for i in range(3): counterThread().start()