()
Wait until the Python thread state of all non-daemon threads get deleted.
Wait until the Python thread state of all non-daemon threads get deleted.
Wait until the Python thread state of all non - daemon threads get deleted .
def _shutdown():
    """
    Wait until the Python thread state of all non-daemon threads get deleted.
    """
    # Obscure:  other threads may be waiting to join _main_thread.  That's
    # dubious, but some code does it.  We can't wait for C code to release
    # the main thread's tstate_lock - that won't happen until the interpreter
    # is nearly dead.  So we release it here.  Note that just calling _stop()
    # isn't enough:  other threads may already be waiting on _tstate_lock.
    if _main_thread._is_stopped:
        # _shutdown() was already called
        return

    global _SHUTTING_DOWN
    _SHUTTING_DOWN = True

    # Call registered threading atexit functions before threads are joined.
    # Order is reversed, similar to atexit.
    for atexit_call in reversed(_threading_atexits):
        atexit_call()

    # Main thread
    if _main_thread.ident == get_ident():
        tlock = _main_thread._tstate_lock
        # The main thread isn't finished yet, so its thread state lock can't
        # have been released.
        assert tlock is not None
        assert tlock.locked()
        tlock.release()
        _main_thread._stop()
    else:
        # bpo-1596321: _shutdown() must be called in the main thread.
        # If the threading module was not imported by the main thread,
        # _main_thread is the thread which imported the threading module.
        # In this case, ignore _main_thread, similar behavior than for threads
        # spawned by C libraries or using _thread.start_new_thread().
        pass

    # Join all non-deamon threads
    while True:
        with _shutdown_locks_lock:
            locks = list(_shutdown_locks)
            _shutdown_locks.clear()

        if not locks:
            break

        for lock in locks:
            # mimic Thread.join()
            lock.acquire()
            lock.release()
def _shutdown ( ) : # Obscure:  other threads may be waiting to join _main_thread.  That's # dubious, but some code does it.  We can't wait for C code to release # the main thread's tstate_lock - that won't happen until the interpreter # is nearly dead.  So we release it here.  Note that just calling _stop() # isn't enough:  other threads may already be waiting on _tstate_lock. if _main_thread . _is_stopped : # _shutdown() was already called return global _SHUTTING_DOWN _SHUTTING_DOWN = True # Call registered threading atexit functions before threads are joined. # Order is reversed, similar to atexit. for atexit_call in reversed ( _threading_atexits ) : atexit_call ( ) # Main thread if _main_thread . ident == get_ident ( ) : tlock = _main_thread . _tstate_lock # The main thread isn't finished yet, so its thread state lock can't # have been released. assert tlock is not None assert tlock . locked ( ) tlock . release ( ) _main_thread . _stop ( ) else : # bpo-1596321: _shutdown() must be called in the main thread. # If the threading module was not imported by the main thread, # _main_thread is the thread which imported the threading module. # In this case, ignore _main_thread, similar behavior than for threads # spawned by C libraries or using _thread.start_new_thread(). pass # Join all non-deamon threads while True : with _shutdown_locks_lock : locks = list ( _shutdown_locks ) _shutdown_locks . clear ( ) if not locks : break for lock in locks : # mimic Thread.join() lock . acquire ( ) lock . release ( )