Thread#stop

Is it possible for one thread to put another thread in a stop (or sleep)
state? (Unlike Thread.stop which stops the current thread.)

The answer is currently no (Thread#stop was removed at one point), and
Matz has said he doesn’t think this should be allowed:

http://blade.nagaokaut.ac.jp/cgi-bin/scat.rb/ruby/ruby-talk/10733

But what about this case:

I’ve got a threaded app with a DRb-based remote debugging/control
interface. I want to stop all non-DRb threads when the user sends the
“stop” command. The the user (or other external process) can then send
more commands to the DRb interface and inspect stuff without those
threads running around like crazy. Then a later call to the DRb
interface can wakeup all the threads that got stopped.

I can’t use Thread.critical, because the DRb interface has to stay awake
for the next request. None of the threads in the DRb group should be
stopped.

Setting the priority of the non-DRb threads very low doesn’t seem to
work either–they keep running when the DRb threads are not running.

Any ideas? If Thread#stop is a bad idea, what is the right idea in this
case?

DÅ?a Piatok 10 Február 2006 05:10 Joel VanderWerf napísal:

Any ideas? If Thread#stop is a bad idea, what is the right idea in this
case?

Letting threads directly play tricks on each other is more of a Q’n’D
hack
than a real parallelism solution. What you’re looking for sounds like a
latch
construct that the user process opens and closes for the other threads.
Brief
googling indicates you could use something called a read-write mutex /
lock.

Maybe there’s a ruby implementation out there already, if not, it should
be
doable via Mutexes and Semaphores. (Do we have Semaphores in the core or
stdlib?)

David V.

David V. wrote:

doable via Mutexes and Semaphores. (Do we have Semaphores in the core or
stdlib?)

David V.

I agree that Thread#stop is not a good tool for writing concurrency
constructs, and Thread.stop should be used instead, as it is in the
implementations of Mutex et al. Thread#stop is bad because the stopped
thread can be stopped in a way that the thread cannot predict or control
(except that it can prevent being stopped by being in Thread.critical).
But that’s exactly why I want it.

Think of this as a remote debugger (in fact, it is). I need all threads
to stop wherever they are except the ones being used to debug the
process. If there were a Thread.critical that applied to all threads in
the DRb ThreadGroup, I’d be happy.

As I understand it, a latch would not serve this purpose. A latch stops
newly created threads from running until the latch is opened. In ruby
this would be easy to implement using Thread.stop within the block of
each thread. Then another thread can wakeup those threads as needed:

th = Thread.new { Thread.stop; do_some_work }
prepare_for_th_to_run
th.wakeup

DÅ?a Piatok 10 Február 2006 21:29 Joel VanderWerf napísal:

As I understand it, a latch would not serve this purpose. A latch stops
newly created threads from running until the latch is opened. In ruby
this would be easy to implement using Thread.stop within the block of
each thread. Then another thread can wakeup those threads as needed:

th = Thread.new { Thread.stop; do_some_work }
prepare_for_th_to_run
th.wakeup

For some strange reason I thought you were using looping worker threads
with
short execution time. Ah well.

David V.

David V. wrote:

For some strange reason I thought you were using looping worker threads with
short execution time. Ah well.

Well, some are fairly short lived, but those ones are fired off by some
“permathreads”. In fact, the are so perma that they have a big rescue
clause with a retry (for StandardErrors) around everything they do.

Still wish I knew how to “freeze frame” all the threads, except the drb
threads that are inspecting them…

DÅ?a Nedeľa 12 Február 2006 08:46 Joel VanderWerf napísal:

David V. wrote:
Well, some are fairly short lived, but those ones are fired off by some
“permathreads”. In fact, the are so perma that they have a big rescue
clause with a retry (for StandardErrors) around everything they do.

Still wish I knew how to “freeze frame” all the threads, except the drb
threads that are inspecting them…

Do those “permathreads” spend a lot of time in an inconsistent state
when it
would be dangerous to stop them? I’m still wondering about the latch
solution, you could possibly sprinkle those long running threads with
waits
on the DRb latch to emulate stopping the threadgroup. Of course, that
might
end up looking really, really ugly with remote debugging code all over
your
logic. Or would this be unviable due to application responsivity?

David V.