On 9/17/05, David Hopwood david.nospam.hopwood@blueyonder.co.uk wrote:
In the case of shared memory concurrency, killing processes asynchronously is a minefield; it is so difficult to do right that IMO it should not be attempted.
Well, of course it shouldn't be done as is. But in as much as we're implementing an Erlang-like system on top of multithreaded Lisps, we precisely have to take into account such things.
That's why a thread should only actually die at a safe point, which is a matter of checking a flag when (yield) is called -- and of course it should by the message system *before* any message is received.
On the other hand, if SBCL does (eventually) provide ways to throw and safely catch asynchronous exceptions, there's no reason not to use them.
The specific reason why asynchronous termination is harder for a language using shared memory concurrency is that, if a thread is killed while it is holding a lock on an object, that object will still be accessible to other threads afterward. At best, the invariants of the object may be violated; at worst, the invariants of the language implementation may be violated, leading to loss of dynamic type safety.
I've formalized this phenomenon in my thesis :) This is why any higher-level concurrent language system must be able to define application invariants that the system will enforce. Erlang makes it possible by decomposing programs into linked processes.
At the implementation level, it's probably not a good idea to attempt to kill threads at arbitrary points; they should only be killed at safe points. Some Lisp implementations may already have a suitable notion of safe point that is used for GC, for example.
Once again, THE SYSTEM-LEVEL NOTION OF SAFE POINT IS NOT THE APPLICATION-LEVEL NOTION OF SAFE POINT, and cannot possibly be you allow the internalization of user-defined atomicity constraints in the language. Erlang works around this in a clever way, rather than attempt to solve the problem. Or maybe, in a way, it *does* provide a solution, but it is unclear (to me) how this solution would be translated in terms of imperative programming with internal side-effects.
[ François-René ÐVB Rideau | Reflection&Cybernethics | http://fare.tunes.org ] We will encourage you to develop the three great virtues of a programmer: laziness, impatience, and hubris. -- LarryWall, Programming Perl (1st edition)