[D-runtime] A mechanism to kill threads

Alex Rønne Petersen xtzgzorex at gmail.com
Wed May 16 16:58:23 PDT 2012


On Thu, May 17, 2012 at 1:51 AM, Brad Roberts <braddr at puremagic.com> wrote:
> If you have code like this, how can you make the claims you have about
> knowing it to be safe to kill the threads in question.  I'm with Sean on
> this, killing threads is a really bad idea and having an api is going to
> result in pain.

I can because I know what the threads are doing. I'm doing this in a
virtual machine; I know the threads are executing isolated, managed
code. Heck, if I wanted, I could map their native instruction pointer
back into my IR to see exactly what operation they were performing.

The important point, however, is that the threads in question can only
mutate state that I know everything about, and I'm doing this daemon
thread killing on shutdown. That means that the managed system is left
in a very fragile state, but it doesn't matter, because the world has
completely stopped at that point (all managed, non-daemon threads have
been joined before killing the daemon threads). This is what I mean
when I say you have to reason about *exactly* what the thread you're
killing is doing, or you shouldn't be killing it at all.

The cases where you can actually kinda-sorta safely kill a thread are
so extremely rare, but they do exist.

>
> The only safe way to do it is akin to what you describe above.  Rely on
> some communication path into the other thread to ask it to kill itself
> when it's actually safe, not just believed to be.

The thing is, that's not so useful in practice: Every programmer
working with my VM would have to make their daemon threads
cooperatively check for a shutdown condition frequently. And while
this is arguably a much better programming model than what people do
today, I can't reasonably force it upon people (it would also render
my VM incompatible with the majority of existing programming languages
in the threading department). Besides, cooperative killing means that
the thread may not be killed at all if the managed code so desires; I
can't afford that. I need to be able to guarantee that the VM shuts
down (well, almost; most thread killing APIs don't actually guarantee
all that much, but in practice, they tend to work).

>
> It's a lot like so called lockless programming.  It's _really_ hard to get
> right.  Even the experts get it wrong fairly frequently.  When you can
> avoid it, avoid it.  There are safe ways of asking a thread to exit
> itself, so that should be the much preferred method.

I really would if I could! But this is a virtual machine, so asking
the thread at some arbitrary point to just shut itself down is not
practical. I know that the thread is executing managed code, but I
don't know *what* that code means; that's entirely up to the
programmer of the application the VM is executing. But as far as VM
shutdown is concerned, what the code does is irrelevant, since I'm
abandoning the managed world completely on shutdown anyway (in
practice, this equals zeroing all of the managed application's
globals, unregistering all roots, doing a GC cycle, and waiting for
finalizers to complete (the last one is another can of worms
entirely...)).

>
> You're obviously a bright guy and know all this, so what's pushing you so
> hard to go in an obviously unsafe direction rather than the obviously safe
> one?

See above. I believe in my specific case, I have enough control to
make this 'safe enough'.

>
> On Thu, 17 May 2012, Alex R?nne Petersen wrote:
>
>> Trust me, I've evaluated every option I could think of. Even
>> cooperative suspension/killing won't cut it because a while (true);
>> inside a VM thread could prevent the cooperative kill from actually
>> happening at all.
>>
>> E.g.:
>>
>> void myThread()
>> {
>>     while (run)
>>     {
>>         runUserCode(); // if this never returns, the thread will never stop
>>     }
>> }
>>
>> Regards,
>> Alex
>>
>> On Thu, May 17, 2012 at 12:55 AM, Sean Kelly <sean at invisibleduck.org> wrote:
>> > On May 16, 2012, at 3:42 PM, Alex R?nne Petersen wrote:
>> >
>> >> The trouble is that they have to have version blocks for every
>> >> platform and every threading library supported. The fact that
>> >> core.thread supports pthreads should not even be known to code that
>> >> extends the Thread class; it's an implementation detail (other
>> >> threading libraries exist, especially on Linux). I believe there is
>> >> currently active work to make GDC support other C libraries, and I
>> >> imagine that involves other threading libraries on rather exotic
>> >> platforms too.
>> >>
>> >> The way I've always seen core.thread is as a fundamental building
>> >> block for threading; it should hide the native threading interface
>> >> completely so people shouldn't have to mess with those at all.
>> >
>> > I tend to agree, though for some of the really risky stuff I think it may be fair to expect the user to be familiar with the platform specifics of what he's trying to do.  Kill threads, for example, works differently on Posix vs. Win32 and is (surprise surprise) actually a bit safer.  Regarding killing threads in general though, I wonder if there isn't perhaps a safer application-specific approach that you could use.  Could these threads periodically check some global "cancel" state and exit if set?  Is it truly necessary to have an external thread violently kill them?
>> > _______________________________________________
>> > D-runtime mailing list
>> > D-runtime at puremagic.com
>> > http://lists.puremagic.com/mailman/listinfo/d-runtime
>> _______________________________________________
>> D-runtime mailing list
>> D-runtime at puremagic.com
>> http://lists.puremagic.com/mailman/listinfo/d-runtime
>>
>
> _______________________________________________
> D-runtime mailing list
> D-runtime at puremagic.com
> http://lists.puremagic.com/mailman/listinfo/d-runtime
>

Regards,
Alex


More information about the D-runtime mailing list