#!/usr/local/cpython-3.7/bin/python3 """Testing threading with a simple scalar global, that is also shared, mutable state.""" # This script outputs, approximately: # Hoping for and got: # 1000000000 # 38303535 # IOW, even for a simple int global, we are not threadsafe and require locking import time import queue try: import thread as thread_mod except ImportError: import _thread as thread_mod # pylint: disable=import-error GLOBAL_COUNTER = 0 NUM_THREADS_TO_START = 1000 NUM_ITERATIONS_IN_EACH_THREAD = 1_000_000 FINISH_QUEUE = queue.Queue(maxsize=NUM_THREADS_TO_START) def increment(threadno): """Increment the counter in a tight loop.""" global GLOBAL_COUNTER for i in range(NUM_ITERATIONS_IN_EACH_THREAD): GLOBAL_COUNTER += 1 FINISH_QUEUE.put(threadno) def main(): """ Test threads. Start a bunch of threads all trying to increment GLOBAL_COUNTER in a tight loop. Then wait for them and print the counter. """ threads = [] for threadno in range(NUM_THREADS_TO_START): print('starting thread # {}'.format(threadno)) threads.append(thread_mod.start_new_thread(increment, (threadno, ))) print('Waiting for threads to exit...') while FINISH_QUEUE.qsize() != NUM_THREADS_TO_START: print('Queue has {} values'.format(FINISH_QUEUE.qsize())) time.sleep(0.5) print('Hoping for and got:\n{}\n{}'.format(NUM_THREADS_TO_START * NUM_ITERATIONS_IN_EACH_THREAD, GLOBAL_COUNTER)) main()