#!/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()