Hacker News new | past | comments | ask | show | jobs | submit login

There's no way to kill goroutines either. In fact, are there any systems that allow you to cleanly kill threads?



Yes.

In Erlang:

    exit(kill).
or exit(Pid,kill).

Will kill a process. It has an isolated heap, so it won't affect other (possibly hundreds of thousands of) running processes. That memory will be garbage collected, safely and efficiently.

This will also work in Elixir, LFE and other languages running on the BEAM VM platform.

EDIT: masklinn user below pointed out correctly, the example is exit/2, that is exit(Pid,kill). In fact it is just exit(Pid, Reason), where Reason can be other exit reason, like say my_socket_failed. However in that case the process could catch it and handle that signal instead of being un-conditionally killed.


This is called from within a threads execution, right? I think the question is about being able to kill a thread externally.

Java had this in 1.0 or 1.1 and then thought better of it and deprecated the API.


> This is called from within a threads execution, right? I think the question is about being able to kill a thread externally.

Yes the GP has the wrong arity, exit/1 terminates the current process but exit/2[0] will send an exit signal to an other process and possibly cause them to terminate (depending on the provided Reason and whether they trap exits).

This is a normal behaviour of Erlang which enables things like seamless supervision trees, where exit signals propagate through the supervision trees reaping all of the processes until they encounter a process trapping exits and a supervisor can freely terminate its children[1]

This can work because erlang doesn't have shared state[2][3], and BEAM implements termination signaling (so processes can be made aware by the VM of the termination of other processes)

[0] http://erlang.org/doc/man/erlang.html#exit-2

[1] http://erlang.org/doc/design_principles/sup_princ.html#id740...

[2] between processes, state is always owned by specific processes and queried/copied out across the process boundary

[3] and thus a process being terminated can't leave inconsistent state behind for others to corrupt themselves (or the VM itself) with


erlang also uses per-actor message queues and has a kill safe design philosophy, so it's not a problem.


It works correctly either way -- externally with exit(Pid,kill) or by the process itself as exit(kill). The last one is just a shorthand for exit(self(), kill). Where self() is the process id of the currently running process.


> It works correctly either way

But the way you showed was not one in which anyone was interested, synchronous exceptions work in more or less every language, and you can't assume readers know your self-killing is actually implemented via asynchronous exceptions since they don't know the language.


Every one I know of has regretted it, and seen it as an antipattern. For example, Java way back in 1.5: http://docs.oracle.com/javase/1.5.0/docs/guide/misc/threadPr...

I think Erlang might be okay with it, because "this thread can fail at any time" is a core value of Erlang. But it's an exception.


Haskell has killThread, which rather than being an anti-pattern is often used as an effective way to accurately enforce a timeout on a thread. This functionality seems like it would be very difficult to achieve with most other runtimes. https://news.ycombinator.com/item?id=11370004


You have a sibling comment elsewhere in the thread which disagrees; I'll leave that argument to that sub-thread.


Yes. In Haskell you use `killThread` which throws an asynchronous exception to the thread. It is certainly difficult to perfectly cleanup resources in the face of asynchronous exceptions. However, once there are functions available to help you with this (e.g. use a bracket function whenever using resources) it becomes tractable.

This functionality is critical to being able to timeout a thread.


AFAIK combining killThread and bracket (or just about anything really) is fraught with issues[0] and hardly qualifies as clean.

[0] http://blog.haskell-exists.com/yuras/posts/handling-async-ex...


Yes, there is still an issue with async exceptions when there is an exception during the cleanup handler of bracket. Probably this has not received the attention it deserves because fundamentally if a cleanup handler throws an exception you may well still have resource issues. But the article also proposes ways of solving this issue, so lets not give up on async exceptions.


GHC has throwTo, which raises an exception in another thread:

http://hackage.haskell.org/package/base-4.6.0.1/docs/Control...

This is used to provide the killThread function:

http://hackage.haskell.org/package/base-4.6.0.1/docs/Control...


Note that this isn't exactly a safe operation, since a killed thread may stop in the midst of something. It's safer to have it process messages on a loop and include a quit message.


POSIX has pthread_cancel. It's a big mess.


Can you clarify what you mean by "kill goroutines?" Because my understanding was if you return while inside a goroutine it get's handled by the GC immediately, and (as someone else mentioned) you can use context to send deadlines/cancellation signals to go routines.


The ability to kill an arbitrary goroutine from the outside. To use context you need to write your specific goroutine such that it checks for cancellation and will eventually handle a cancellation request. This cannot be done with an arbitrary goroutine.


You can use contexts to send a cancellation signal to goroutines: https://blog.golang.org/context.

This is more of an implementation detail you make on a case-by-case language rather than a builtin to go.


That's not a way to "kill goroutines". That's a way to "ask goroutines to die when they get around to it." Useful, but a fundamentally different thing. Go does not have a way to kill goroutines, nor, per some of the other discussion in this thread, do I ever expect it to.




Guidelines | FAQ | Lists | API | Security | Legal | Apply to YC | Contact

Search: