On 9/29/10, Robert Klemme <shortcutter / googlemail.com> wrote:
> Without going into too much detail I believe one flaw of your design
> here is that you are not using thread synchronization but instead try to
> explicitly start and stop threads and yield execution.  It may be that
> this is causing your cores, but I really don't know.

I agree that in general it's better to do this kind of thing using the
appropriate synchronization data structures... however, I should
expect that it is not possible to crash the ruby interpreter purely by
writing ruby code, regardless of the presence of bugs in it. I don't
know whether it is possible to actually achieve this level of
reliability when dealing with threading code that contains race
conditions, tho.

> What I would do:
>
> 1. Use a condition variable to let all threads start at the same time.
[snip]
> lock.synchronize do
>    start = true
>    cond.signal
> end

Putting aside my prejudices against ConditionVariable, there is
another problem with this: ConditionVariable#signal awakens only one
thread waiting on the condvar. You'd want to use
ConditionVariable#broadcast instead. But even then, there is a race
condition; you're not guaranteed that all the threads have blocked
waiting on the condvar. Some may still be running the code before that
point, and they would end up never running to completion. A counting
semaphore could solve that, but ruby doesn't actually have one of
those (sigh).

Thread synchronization is a real PITA.

I see now that the first line of ConditionVariable#broadcast is this:
  # TODO: imcomplete
So, maybe there's some kind of problem with it?

> You can probably get away without the condition variable by just
> acquiring the lock (lock.synchronize) in the main thread before you
> create all threads and let all threads just synchronize with an empty block.

I can't see any holes in this scheme, so it's probably the best idea.