Re: Something is wrong with my threads

Ryan Davis <[email protected]>
Newsgroups gmane.comp.lang.ruby.general
Message-ID <[email protected]>
> On Apr 17, 2019, at 08:31, Andy Jones <[email protected]> wrote:
> 
> Would any of you smart folks like to tell me what stupid thing I am doing here?

SO MANY THINGS!

First off, you’re coding in a proportional font, and that always leads to bugs. :P

More seriously, I’ll comment inline and then provide my counter example:

> require “time"

You don’t need this require to use Time.now.

> def make_thread(idx)

I would avoid having a make_threads method. Methods are opaque, and often you create threads to do work from a queue. You can pass everything in to your make_threads method, or you can just use blocks.

>   Thread.new do
>     # Set things up and wait
>     Thread.current[:idx] = idx
>     Thread.stop

Why call Thread.stop, at all? What do you care? This smells of a control issue.

>     # do the work, then say we're done
>     Thread.current[:done] = true

I generally don’t store state in my threads. Threads are usually workers, not containers. They usually get data from some source, do work, and then put resultant data into another source.

>     Thread.stop

Ditto to #stop above. This thread would have been done if this line wasn’t here at all and it got to the end of it’s block. Control issues. Let go.

>   end
> end
>  
>  
> threads = []; 1.upto(200){|i| threads << make_thread(i) }

container = []; something.each { container << thing }

is the implementation for:

container = something.map { thing }

> starttm = Time.now
>  
> # Do the work
> threads.each{|t| t.run }

They would be running if you didn’t stop them.

> # Wait until all work is done or we time out
> sleep 0.1 until (threads.all?{|t| t[:done] } || Time.now >= starttm + 10)

I don’t get this. Leave them alone. Use Thread#join to let them finish their work and stop on their own.

> # If all work is not done, something has gone very wrong?
> fails = threads.reject{|t| t[:done] }
> if fails.size > 0
>   puts "FAIL"
>   fails.each{|e| puts "#{e[:idx]}: #{e.alive?}" }
> end

Don’t poke at your threads. It makes them angry.

-----

Here’s my counter:

t0 = Time.now

threads = 200.times.map { |i|
  Thread.new do
    Thread.current[:idx] = i # not necessary

    sleep 1                  # lots of "work"
  end
}

threads.each(&:join)         # finish working

p Time.now - t0

# => 1.013938


Unsubscribe: <mailto:[email protected]?subject=unsubscribe>
<http://lists.ruby-lang.org/cgi-bin/mailman/options/ruby-talk>
lmpx.com only provides a reader for public news (NNTP) servers. It is not affiliated with the servers or forums shown here and is not responsible for the content of articles, which is written by their respective authors.