# Ruby Threading question Creating 4 threads

**URL:** <https://www.ruby-forum.com/t/ruby-threading-question-creating-4-threads/160485>\
**Category:** Ruby\
**Created:** [February 16, 2009, 10:52pm UTC](https://www.ruby-forum.com/t/ruby-threading-question-creating-4-threads/160485 "2009-02-16T22:52:49Z")\
**Posts on this page:** 7\
**Page:** 1

<div class="post-metadata">

**Author:** ![tristincolby](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/t/58f4c7/32.png) [@tristincolby](https://www.ruby-forum.com/u/tristincolby)\
**Post date:** [February 16, 2009, 10:52pm UTC](https://www.ruby-forum.com/t/ruby-threading-question-creating-4-threads/160485/1 "2009-02-16T22:52:49Z")

</div>

Newbie Question:

I have some code where I create 4 threads that pop elements off an  
array and process them. The problem is that each thread only pops off  
one element, processes it, then returns; they don’t continue to  
process until the entire array is consumed.

`
$jobs = %w[a b c d e f g]
def simulate_cleanup
puts “Checking for #{$jobs.length} jobs in /mnt/gen1/focal/temp”
threads = []
mu = Mutex.new
total = 0
1.upto(4) do |c|
threads << Thread.new do
puts “Thread #{c} created”
job = nil
```
  mu.synchronize do
    job = $jobs.pop
    puts "Checking for #{job}"
    #Exit our thread if we have no more jobs to check
    puts "No more jobs" and return if job.nil?
  end

  t = count_files(job)
  mu.synchronize { total += t }
end

```
end
threads.each { |t| t.join }
puts “Reduced by #{total} files”
end
Example of output:
Thread 1 created
Thread 2 created
Thread 3 created
Thread 4 created
Checking for a
Checking for b
Checking for c
Checking for d`

---

<div class="post-metadata">

**Author:** ![tristincolby](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/t/58f4c7/32.png) [@tristincolby](https://www.ruby-forum.com/u/tristincolby)\
**Post date:** [February 16, 2009, 11:11pm UTC](https://www.ruby-forum.com/t/ruby-threading-question-creating-4-threads/160485/2 "2009-02-16T23:11:12Z")

</div>

what if you put your thread body in an infinite loop, something like:

Thread.new do  
loop do  
puts “Thread #{c} created”  
job = nil

```
 mu.synchronize do
   job = $jobs.pop
   puts "Checking for #{job}"
   #Exit our thread if we have no more jobs to check
   puts "No more jobs" and Thread.exit if job.nil?
 end

 t = count_files(job)
 mu.synchronize { total += t }

```

end  
end

and as you may have noticed, I replaced the ‘return’ statement inside  
your  
thread with a ‘Thread.exit’ method.  
I think it would be the right way to do it…

2009/2/16 [removed\_email\_address@domain.invalid](mailto:removed_email_address@domain.invalid)

---

<div class="post-metadata">

**Author:** ![tristincolby](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/t/58f4c7/32.png) [@tristincolby](https://www.ruby-forum.com/u/tristincolby)\
**Post date:** [February 16, 2009, 11:20pm UTC](https://www.ruby-forum.com/t/ruby-threading-question-creating-4-threads/160485/3 "2009-02-16T23:20:39Z")

</div>

and looking at it more, I think it would be better to leave the less  
stuff  
in the mutex block as possible,  
making it something something like:

mu.synchronize do  
job = $jobs.pop  
end

puts “Checking for #{job}”  
#Exit our thread if we have no more jobs to check  
puts “No more jobs” and Thread.exit if job.nil?

I guess the Thread.exit could have caused a deadlock if inside the  
mutex,  
and since the mutex locks your other threads you better keep it as small  
as  
possible for efficiency sake.

2009/2/16 Louis-Philippe [removed\_email\_address@domain.invalid](mailto:removed_email_address@domain.invalid)

---

<div class="post-metadata">

**Author:** ![tristincolby](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/t/58f4c7/32.png) [@tristincolby](https://www.ruby-forum.com/u/tristincolby)\
**Post date:** [February 17, 2009, 4:39am UTC](https://www.ruby-forum.com/t/ruby-threading-question-creating-4-threads/160485/4 "2009-02-17T04:39:12Z")

</div>

Put a while around the pop and block of code to run.

Blog: [http://random8.zenunit.com/](http://random8.zenunit.com/)  
Learn rails: [http://sensei.zenunit.com/](http://sensei.zenunit.com/)

---

<div class="post-metadata">

**Author:** ![tristincolby](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/t/58f4c7/32.png) [@tristincolby](https://www.ruby-forum.com/u/tristincolby)\
**Post date:** [February 17, 2009, 8:25am UTC](https://www.ruby-forum.com/t/ruby-threading-question-creating-4-threads/160485/5 "2009-02-17T08:25:33Z")

</div>

On 17.02.2009 04:38, Julian L. wrote:

> Put a while around the pop and block of code to run.

Also class Queue has thread safety built in already.

Kind regards

robert

---

<div class="post-metadata">

**Author:** ![tristincolby](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/t/58f4c7/32.png) [@tristincolby](https://www.ruby-forum.com/u/tristincolby)\
**Post date:** [February 17, 2009, 4:41am UTC](https://www.ruby-forum.com/t/ruby-threading-question-creating-4-threads/160485/6 "2009-02-17T04:41:33Z")

</div>

That won’t ever exit the thread because puts returns nil.

Blog: [http://random8.zenunit.com/](http://random8.zenunit.com/)  
Learn rails: [http://sensei.zenunit.com/](http://sensei.zenunit.com/)

---

<div class="post-metadata">

**Author:** ![tristincolby](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/t/58f4c7/32.png) [@tristincolby](https://www.ruby-forum.com/u/tristincolby)\
**Post date:** [February 17, 2009, 3:14pm UTC](https://www.ruby-forum.com/t/ruby-threading-question-creating-4-threads/160485/7 "2009-02-17T15:14:56Z")

</div>

Robert K. wrote:

> On 17.02.2009 04:38, Julian L. wrote:
> 
> > Put a while around the pop and block of code to run.
> 
> Also class Queue has thread safety built in already.
> 
> Kind regards
> 
> robert

…an example of using a Queue:

require ‘thread’

arr = %w[a b c d e f g h i j]  
num\_threads = 4  
q = Queue.new

workers = []

num\_threads.times do |i|  
workers \<\< Thread.new(“worker#{i+1}”) do |name|  
loop do  
data = q.pop #pops data off bottom of q, blocks if no data  
puts “#{name} retrieved data: #{data}”  
break if data == “_END\_OF\_DATA\_FLAG_”  
end  
end  
end

arr.each {|item| q.push(item)}  
num\_threads.times do  
q.push(“_END\_OF\_DATA\_FLAG_”)  
end

workers.each {|thr| thr.join}  
puts “Workers are all done working.”

–output:–  
worker1 retrieved data: a  
worker2 retrieved data: b  
worker3 retrieved data: c  
worker4 retrieved data: d  
worker1 retrieved data: e  
worker2 retrieved data: f  
worker3 retrieved data: g  
worker4 retrieved data: h  
worker1 retrieved data: i  
worker2 retrieved data: j  
worker3 retrieved data: _END\_OF\_DATA\_FLAG_  
worker4 retrieved data: _END\_OF\_DATA\_FLAG_  
worker1 retrieved data: _END\_OF\_DATA\_FLAG_  
worker2 retrieved data: _END\_OF\_DATA\_FLAG_  
Workers are all done working.
