2

I have two questions regarding the state of a thread created in managed code by the CLR.

  1. There appears to be no thread state to represent a thread waiting on a blocked I/O operation.

    For e.g. waiting on a disk driver to respond with a stream of bytes read from the disk, or waiting on a network port for a stream of bytes to arrive from another process or computer.

    Why is that? Or if that isn't the case, could you please tell me which member of the ThreadState enumeration represents this state?

    The closest I came to find was the WaitSleepJoin state, but its documentation reads as follows:

    WaitSleepJoin

    The thread is blocked. This could be the result of calling Thread.Sleep or Thread.Join, of requesting a lock — for example, by calling Monitor.Enter or Monitor.Wait — or of waiting on a thread synchronization object such as ManualResetEvent.

  2. From the excerpt of the documentation reproduced above, please consider this phrase:

    ...of requesting a lock — for example, by calling Monitor.Enter or Monitor.Wait

    Why would a thread block if it simply requested for a lock? Does that documentation actually imply, "While waiting for a lock, presently held by another thread, on a resource to be released. In other words, during a SpinWait? In other words, while waiting to be pulsed by the present owner of the lock?"

Water Cooler v2
  • 32,724
  • 54
  • 166
  • 336
  • As for 2 - yes, it's implied that thread is blocked by waiting for the lock to be released by current owner (though not related to SpinWait in any way). – Evk May 22 '16 at 14:57
  • @Evk Thank you. If it doesn't `SpinWait`, it yields back to the OS and is put back on the *wait queue*, right? Just like `Sleep` or `Yield`, right? So, in that way, it doesn't *have* to be spinning and waiting? That's what you meant by *not related to SpinWait in any way*, right? – Water Cooler v2 May 22 '16 at 15:04
  • You can read a bit about internals of lock (and so - Monitor.Enter\Exit) here for example: http://stackoverflow.com/a/5144801/5311735. So basically it first spins for a _very_ brief time, but then is put in wait queue about as you said. So most of the time it does not spin and not wastes CPU cycles. – Evk May 22 '16 at 15:09
  • @Evk Yes, thank you, it was my previous knowledge, as the thread you linked to confirms, that the default implementation of the .NET `Monitor` puts the thread into a spin-wait for a period of time not more than the time it takes to transition into the kernel mode. Because otherwise, spinning and waiting would be costlier than a context switch and would be pretty much useless. – Water Cooler v2 May 22 '16 at 15:40
  • 1
    As for your 1 - I made small test using blocking TcpListener.AcceptSocket call and observing thread state of that thread (which was blocked by AcceptSocket call) from another thread. It never entered SleepWaitJoin and was always in Running state, so I suppose that there is no state indication for at least such blocking operations. – Evk May 22 '16 at 15:43
  • @Evk Thank you very much. That means, it is never possible in .NET (unless you side-step the CLR and use the Win32 synchronization primitives or you called `Abort`) to recall / interrupt a thread that is doing some I/O stuff. :-) If you would like to put that down as an answer, I would like to mark it as the right one. – Water Cooler v2 May 22 '16 at 15:48
  • Do you have some specific problem to solve or just asking our of interest? Because most blocking operations either provide means to cancel it (for example to cancel that pending AcceptSocket you can just close TcpListener) or at least provide timeouts. – Evk May 22 '16 at 16:03
  • @Evk I am asking because I am learning. I am not yet implementing anything. – Water Cooler v2 May 22 '16 at 16:07

0 Answers0