“Robert Klemme” bob.news@gmx.net writes:
- One thread’s complete state is cloned and resumed in another thread
context. That means effectively that on thread disappears. And suddenly
you would have to solve all kinds of synchronization problems you weren’t
expecting: assume, you use an instance X in one thread that is thread local
[cut]
- The invocation of the continuation makes the continuation’s original
thread stop and resume the continuation. This will lead to unexpected
context switches and all kinds of strange behavior. And what happens to the
calling thread? Where does execution resume? Is the call suddenly
asynchronous? That would not fit well with the rest of Ruby since all
[cut]
In short: I don’t see how continuations and threads mix well.
Regards
robert
Hi,
I find your reply interesting, but am not sure whether you are saying
that continuations and threads do not mix well conceptually or as they
are currently implemented in current official ruby implementation.
Conceptually, I do not find any issue in mixing continuations and
threads. They are distinctly separate concepts. Continuations saves
the execution state at that point. A possible implementation would
probably save the control and binding stacks as what Allergo CL does:
“The control stack maintains the function evaluation state including
lexical bindings. The binding stack records the dynamic bindings of
special variables.” (http://tinyurl.com/2hgxw)
Meanwhile, threads are simply streams-of-executions. Resuming a
continuation, then, should be just-another-thing-to-execute. And one
can adopt Scheme’s semantic in continuation resumption, that is to
“abandon whatever continuation is in effect … and will instead use
the continuation that was in effect when the [continuation object was
created]” (Project MAC Home Page).
So, to address the concerns you raised above:
Concern #1. I certainly agree this is a valid concern. However, I am
also a proponent of responsible programmer. Thus, I see that the
responsibility to mix threads and continuations should lie on the
programmers. The programmers should know what he is doing. I think
it is reasonable to expect at least this much responsibility from
the programmer (“enabling” – Software Development Attitude). In any
case, this concern does not introduce any new responsibility to
programmers coding non-trivial multi-threaded program: be careful
when sharing common resources.
Concern #2. The thread that creates the continuation objects need not
stop, in fact there is no reason for it to stop. The calling thread
should just resume the continuation at the resumption point, which
in ruby is the next statement after the callcc{} statement.
So, running the following code (won’t run with current official ruby
implementation):
Thread.new {
Thread.current[:id] = 1
puts “#{Thread.current[:id]} A”
callcc{|c|
puts “#{Thread.current[:id]} B”
Thread.new {
Thread.current[:id] = 2;
c.call
}
puts “#{Thread.current[:id]} C”
}
puts “#{Thread.current[:id]} D”
}
would result in (may vary depending on thread scheduling):
1 A
1 B
1 C
1 D
2 D
As Eric Hodel pointed out elsewhere in this posting thread, the
problem lies in the current implementation: continuations are
implemented in terms of threads. Thus, they are no longer distinct
entities and, apparently, one of the consequence is that you can’t
call continuations from across threads. It will also brings out other
ugly things mentioned in your concern #2. So, apparently, what you
were saying are wrt current ruby implementation.
WRT my original problem that would have benefited from a continuation
that is callable across threads, I have found that Eric Hodel’s
suggestion works acceptably.
Thank you,
YS.