sys includes low-level functions for controlling and debugging thread behavior.

Switch Interval¶

Python 3 uses a global lock to prevent separate threads from corrupting the interpreter state. After a configurable time interval, bytecode execution is paused and the interpreter checks if any signal handlers need to be executed. During the same check, the global interpreter lock (GIL) is also released by the current thread and then reacquired, with other threads given priority over the thread which has just released the lock.

The default switch interval is 5 milliseconds and the current value can always be retrieved with sys.getswitchinterval() . Changing the interval with sys.setswitchinterval() may have an impact on the performance of an application, depending on the nature of the operations being performed.

sys_switchinterval.py ¶ import sys import threading from queue import Queue def show_thread ( q ): for i in range ( 5 ): for j in range ( 1000000 ): pass q . put ( threading . current_thread () . name ) return def run_threads (): interval = sys . getswitchinterval () print ( 'interval = {:0.3f} ' . format ( interval )) q = Queue () threads = [ threading . Thread ( target = show_thread , name = 'T {} ' . format ( i ), args = ( q ,)) for i in range ( 3 ) ] for t in threads : t . setDaemon ( True ) t . start () for t in threads : t . join () while not q . empty (): print ( q . get (), end = ' ' ) print () return for interval in [ 0.001 , 0.1 ]: sys . setswitchinterval ( interval ) run_threads () print ()

When the switch interval is less than the amount of time a thread takes to run to completion, the interpreter gives another thread control so that it runs for a while. This is illustrated in the first set of output where the interval is set to 1 millisecond.

For longer intervals, the active thread will be able to complete more work before it is forced to release control. This is illustrated by the order of the name values in the queue in the second example using an interval of 10 milliseconds.

$ python3 sys_switchinterval.py interval = 0.001 T0 T1 T2 T1 T0 T2 T0 T1 T2 T1 T0 T2 T1 T0 T2 interval = 0.100 T0 T0 T0 T0 T0 T1 T1 T1 T1 T1 T2 T2 T2 T2 T2

Many factors other than the switch interval may control the context switching behavior of Python’s threads. For example, when a thread performs I/O it releases the GIL and may therefore allow another thread to take over execution.