import threading
from atexit import register
from random import randrange
from threading import Thread, Lock
from time import sleep, ctime

lock = Lock()
loops = (randrange(2, 5) for x in range(randrange(3, 7)))
print(loops)


class CleanOutputSet(set):
    def __str__(self):
        return ','.join(x for x in self)


remaining = CleanOutputSet()


def loop(sec):
    myname = threading.current_thread().name
    with lock:
        remaining.add(myname)
        print('[%s] started %s' % (ctime(), myname))

    sleep(sec)

    with lock:
        remaining.remove(myname)
        print('[%s] completed %s (%d sec)' % (ctime(), myname, sec))
        print('remaining : %s' % (remaining or 'None'))


def _main():
    for p in loops:
        Thread(target=loop, args=(p,)).start()


@register
def _atexit():
    print('all done at:', ctime())


if __name__ == '__main__':
    _main()
    # for i in loops:
    #     print(i)