Re: How do you kill a completly locked up thread?
- From: Jeroen Mostert <jmostert@xxxxxxxxx>
- Date: Wed, 16 Jan 2008 20:26:47 +0100
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.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.
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?
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.
.
- Follow-Ups:
- Re: How do you kill a completely locked up thread?
- From: TheSilverHammer
- Re: How do you kill a completely locked up thread?
- Prev by Date: Re: I cannot reliably write the Hex number "83" to a stream
- Next by Date: Re: Programmatically check to make sure an e-mail address is legit.
- Previous by thread: RE: How do you kill a completly locked up thread?
- Next by thread: Re: How do you kill a completely locked up thread?
- Index(es):
Relevant Pages
|