(Execution) Termination bit, Alternation bit.

eryk sun eryksun at gmail.com
Sun Dec 20 23:04:24 EST 2015


On Sun, Dec 20, 2015 at 10:21 AM, Dennis Lee Bieber
<wlfraed at ix.netcom.com> wrote:
> On Sun, 20 Dec 2015 12:25:30 +0100, "Skybuck Flying"
> <skybuck2000 at hotmail.com> declaimed the following:
>>
>>This does make me wonder how Windows 7 terminates threads/processes/hanging
>>applications.
>>
>>Apperently there is some kind of mechanism for this.
>>
>         And if you've done it you'll have seen warnings about possible data
> corruption or further misbehavior of the system.

The Windows mechanism for queueing a routine to run on another thread
is an NT asynchronous procedure call (APC). Here's an old article
about NT APCs (Almeida, 2002):

    http://www.drdobbs.com/184416590

APCs are typically used by kernel-mode code in the I/O system and
drivers. A user-mode APC can also be queued to a thread using
QueueUserAPC, but it only executes "with permission" when the thread
either calls ntdll!NtTestAlert or enters an alertable wait.

TerminateThread calls the system function NtTerminateThread, which
queues an APC to the thread to call the process manager private
function nt!PspExitThread. The thread rundown procedure is briefly as
follows:

    * Notify driver callbacks registered via
      PsSetCreateThreadNotifyRoutine.
    * If it's the last thread in the process, wait
      for all other threads to finish exiting.
    * Message any debug or termination port.
    * Run down the Win32 extended thread.
    * Cancel outstanding I/O operations, timers, and
      registry notifications.
    * Run down the kernel thread.
    * Delete the thread environment block (TEB).
    * Run down the LPC message stack.
    * Set the thread ExitStatus and ExitTime.
    * If it's the last thread in the process, close
      out the process handle table and section object.
    * Run down pending APCs.
    * Queue the thread to be reaped.

ExitThread (i.e. ntdll!RtlExitUserThread) calls the loader function
ntdll!LdrShutdownThread. This gives all interested DLL entrypoints and
TLS initializers an opportunity to do required bookkeeping and
resource management for the detaching thread. Then RtlExitUserThread
calls NtTerminateThread to let the executive handle the rest.

CPython calls the C runtime's _endthreadex, which is recommended in
place of calling ExitThread directly, especially if the CRT is linked
statically instead of as a DLL.

> In both cases the preferred method is for the process/thread ITSELF to call
> Exit(Process|Thread) in response to some other signal that it reads.

Yes, in C/C++ code. In Python code just return or raise SystemExit to
let the interpreter do this for you. Calling either ExitThread or
_endthreadex directly is a bad idea. Python's DllMain doesn't handle a
DLL_THREAD_DETACH when _endthreadex or ExitThread is called. Thus if
you pull the rug out from under the thread, the thread's tstate lock
is never released and the interpreter will hang at exit if it isn't a
daemon thread.



More information about the Python-list mailing list