Re: How do you kill a completly locked up thread?



TheSilverHammer wrote:
Because C# has no native SSH class, I am using SharpSSH. Sometimes, for reasons I do not know, a Connect call will totally lock up the thread and never return. I am sure it has something to do with weirdness going on with the server I am talking to. Anyhow, this locked up state happens once in a while (maybe once per day) and I can't figure out how to deal with the locked up thread.

If I issue a Thread.Abort() the exception never gets thrown in the thread because it is locked up. This seems to be the only C# method I know of to kill a thread. Is there some other way to kill off a thread?

Yes, the unmanaged TerminateThread(). However, this doesn't work, in that it will kill off the thread, but leave approximately zero chance for your application to continue running successfully. You are guaranteed to corrupt internal state with this, especially since the CLR gets no chance to cleanly release resources associated with that thread. Seriously, don't do this. Your application will probably just deadlock later on the locks the terminated thread was holding, if it doesn't just crash on corrupted state.

Also, there's no obvious way to find the thread that's blocking. For one thing, you can kill off the thread corresponding to the Thread object, but this is not guaranteed to be the thread doing the actual blocking I/O, it might just be waiting on another thread. As a result, you've just leaked a thread that's still busy blocking, and worse, the actual I/O is still in progress, so the socket is unusable. You don't want to repeat this exercise, as it's a good way to run out of resources fast.

A way you can simulate this yourself, is create any thread that connects to a server where the connection takes some time, like 10 to 20 seconds. When the thread is doing this connect (it will happen with even a simple TCP/IP socket connect) issue a Thread.Abort() from another thread (the one that made the Thread Object) and you will see that the ThreadAbortException will NOT be thrown until the Connect call returns.

Correct. The thread is blocking on I/O, in unmanaged code. You can't end it, and this is more or less by design. But you shouldn't be too dismayed, because Thread.Abort() is a bad idea for the same reasons TerminateThread() is. If a thread needs to end, it should be designed to have exit points where the application state is known, and it can check a flag or issue a wait on a user object at those points. Raising an exception in the middle of anywhere is a good way of corrupting global state.

Another way you can do this is after the connect call is finished and you start to talk to a server, if you are on a recive data call and the server stops sending data but never closes the connection, it will block forever. You will once again not be able to get Thread.Abort() to kill the locked up thread.

Same thing.

Is there anyone, especially a MSVP who can answer this?

I'm not an MSVP but I've seen this so many times in our codebase that it's not funny anymore. The one way to cancel pending I/O on a socket and unwedge threads blocking on that is to close the socket from another thread and handle the resulting exceptions. Nothing else will do, at least nothing that can be called reliable. Of course, this means tearing down the connection, but that's still a whole lot better than tearing down your process.

The other alternative, which is less straightforward but suits some designs better, is to make sure that threads never issue I/O which can take "forever". Almost every I/O call has a timeout parameter, and for those that don't there's always asynchronous I/O and ThreadPool.RegisterWaitForSingleObject(). When the call returns with a timeout, either poll, decide to wait some more or give up and close the socket, which you can then do from the same thread that owns the socket, simplifying error handling.

I understand it's not your code, but trust me: you'll want to rewrite it anyway, unless you can afford restarting your application every so often.

--
J.
.



Relevant Pages

  • Re: How do you kill a completely locked up thread?
    ... The one way to cancel pending I/O on a socket and unwedge ... // Call BeginInvoke on delegate. ... // Note on last two parameters of Delegate BeginInvoke Method: ...
    (microsoft.public.dotnet.languages.csharp)
  • Re: http webserver using select()
    ... "Binding" file descriptor with open file to accepted socket descriptor ... fds for each connection. ... generate socket fd via socket-> listening socket ... For other 1 bits in fd_set, handle I/O ...
    (comp.unix.programmer)
  • Re: Does WSASetBlockingHook *really* work on WIN2K
    ... So, is there some way to get single-threaded win32 blocking hooks to work on an NT-based system, or do I need to move to a separate I/O thread? ... Only problem with this is that when I do long file transfers (which the app does in 4K chunks), the overhead of creating and destroying a thread for each 4K read slows the app down unacceptably. ...
    (microsoft.public.win32.programmer.networks)
  • Re: java socket i/o with callback/non-blocking
    ... Basically I want to have some subroutine to be called whenever there is data available to read on a socket object without having to poll it. ... Note also that the technique described is blocking, not non-blocking, as indeed is the technique you described even if the channel is in non-blocking mode. ... For just one socket, you are probably much better off to dump all the NIO stuff, and simply use blocking I/O in its own thread. ...
    (comp.lang.java.programmer)
  • Re: reading async from socket
    ... for a client it usually doesn't ... make sense going for a server I/O model. ... Does using WSARecv means opening the socket using WSASocket with that ... my client app needs to ...
    (microsoft.public.win32.programmer.networks)