# Threads and synchronized access to an array

**URL:** <https://www.ruby-forum.com/t/threads-and-synchronized-access-to-an-array/140822>\
**Category:** Ruby\
**Created:** [June 18, 2008, 11:24pm UTC](https://www.ruby-forum.com/t/threads-and-synchronized-access-to-an-array/140822 "2008-06-18T23:24:16Z")\
**Posts on this page:** 4\
**Page:** 1

<div class="post-metadata">

**Author:** ![syg6](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/s/439d5e/32.png) [@syg6](https://www.ruby-forum.com/u/syg6)\
**Post date:** [June 18, 2008, 11:24pm UTC](https://www.ruby-forum.com/t/threads-and-synchronized-access-to-an-array/140822/1 "2008-06-18T23:24:16Z")

</div>

# Hi everyone! A n00b question - I have a following ruby code:

@arr = [1, 2, 3, 4, 5, 6, 7, 8]

def iterate(thread\_number)  
@arr.each do |line|  
puts “#{line} - I am thread number #{thread\_number}”  
end  
end

number\_of\_threads = 4

threads = []  
number\_of\_threads.times do |t|  
threads[t] = Thread.new do  
iterate(t)  
end  
end

# threads.each {|t| t.join}

# The output for this code is:

# 1 - I am thread number 0 2 - I am thread number 0 3 - I am thread number 0 4 - I am thread number 0 5 - I am thread number 0 6 - I am thread number 0 7 - I am thread number 0 8 - I am thread number 0 1 - I am thread number 1 2 - I am thread number 1 3 - I am thread number 1 4 - I am thread number 1 5 - I am thread number 1 6 - I am thread number 1 7 - I am thread number 1 8 - I am thread number 1 1 - I am thread number 2 2 - I am thread number 2 3 - I am thread number 2 4 - I am thread number 2 5 - I am thread number 2 6 - I am thread number 2 7 - I am thread number 2 8 - I am thread number 2 1 - I am thread number 3 2 - I am thread number 3 3 - I am thread number 3 4 - I am thread number 3 5 - I am thread number 3 6 - I am thread number 3 7 - I am thread number 3 8 - I am thread number 3

# What should be changed in this code to make the output looks like this?

# 1 - I am thread number #{thread\_number} 2 - I am thread number #{thread\_number} 3 - I am thread number #{thread\_number} 4 - I am thread number #{thread\_number} 5 - I am thread number #{thread\_number} 6 - I am thread number #{thread\_number} 7 - I am thread number #{thread\_number} 8 - I am thread number #{thread\_number}

I want to iterate the array values only one time by some number of  
threads, how should I control the access to array values? Each thread  
must be prohobited from using the array values, which have been already  
used by other threads.

I was trying to change the code like this:  
@mutex = Mutex.new  
@arr = [1, 2, 3, 4, 5, 6, 7, 8]

@mutex.synchronize {  
def iterate(thread\_number)  
@arr.each do |line|  
puts “#{line} - I am thread number #{thread\_number}”  
end  
end  
}

number\_of\_threads = 4

threads = []  
number\_of\_threads.times do |t|  
threads[t] = Thread.new do  
iterate(t)  
end  
end

threads.each {|t| t.join}

and this:  
@mutex = Mutex.new  
@arr = [1, 2, 3, 4, 5, 6, 7, 8]

def iterate(thread\_number)  
@arr.each do |line|  
puts “#{line} - I am thread number #{thread\_number}”  
end  
end

number\_of\_threads = 4

threads = []  
number\_of\_threads.times do |t|  
threads[t] = Thread.new do  
@mutex.synchronize {  
iterate(t)  
}  
end  
end

threads.each {|t| t.join}

---

<div class="post-metadata">

**Author:** ![syg6](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/s/439d5e/32.png) [@syg6](https://www.ruby-forum.com/u/syg6)\
**Post date:** [June 19, 2008, 12:12am UTC](https://www.ruby-forum.com/t/threads-and-synchronized-access-to-an-array/140822/2 "2008-06-19T00:12:48Z")

</div>

On Jun 18, 2008, at 5:23 PM, Bob Bobrov wrote:

> ================================================  
> 6 - I am thread number 0  
> 1 - I am thread number 2  
> 4 - I am thread number 3  
> 1 - I am thread number #{thread\_number}  
> threads, how should I control the access to array values? Each thread  
> @arr.each do |line|  
> iterate(t)  
> def iterate(thread\_number)  
> threads[t] = Thread.new do  
> @mutex.synchronize {  
> iterate(t)  
> }  
> end  
> end
> 
> threads.each {|t| t.join}

Perhaps:

require ‘thread’

@mutex = Mutex.new  
@arr = [1, 2, 3, 4, 5, 6, 7, 8]

def iterate(thread\_number)  
while @arr.length \> 0 do  
sleep 0.01  
@mutex.synchronize {  
if line = @arr.shift  
puts “#{line} - I am thread number #{thread\_number}”  
end  
}  
end  
end

number\_of\_threads = 4

threads = []  
number\_of\_threads.times do |t|  
threads[t] = Thread.new do  
iterate(t)  
end  
end

threads.each {|t| t.join}

**END**

without the sleep, the first thread started grabs them all before the  
next one gets a chance. You never did anything to alter the @arr that  
all threads saw.

I haven’t played with threads for a long time, but unless you change  
something about @arr, every iterate() will operate once for each  
element. You run into trouble with the Array#each if you modify the  
contents of the array inside the block.

-Rob

Rob B. [http://agileconsultingllc.com](http://agileconsultingllc.com)  
removed\_email\_address@domain.invalid

---

<div class="post-metadata">

**Author:** ![syg6](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/s/439d5e/32.png) [@syg6](https://www.ruby-forum.com/u/syg6)\
**Post date:** [June 19, 2008, 12:56pm UTC](https://www.ruby-forum.com/t/threads-and-synchronized-access-to-an-array/140822/3 "2008-06-19T12:56:05Z")

</div>

Rob B. wrote:

> def iterate(thread\_number)  
> while @arr.length \> 0 do  
> sleep 0.01  
> @mutex.synchronize {  
> if line = @arr.shift  
> puts “#{line} - I am thread number #{thread\_number}”  
> end  
> }  
> end  
> end

Thank you, exactly what I need!

---

<div class="post-metadata">

**Author:** ![syg6](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/s/439d5e/32.png) [@syg6](https://www.ruby-forum.com/u/syg6)\
**Post date:** [June 19, 2008, 12:17am UTC](https://www.ruby-forum.com/t/threads-and-synchronized-access-to-an-array/140822/4 "2008-06-19T00:17:28Z")

</div>

On Jun 18, 2008, at 6:11 PM, Rob B. wrote:

> On Jun 18, 2008, at 5:23 PM, Bob Bobrov wrote:
> 
> > # Hi everyone! A n00b question - I have a following ruby code:

snip

> > I want to iterate the array values only one time by some number of  
> > threads, how should I control the access to array values? Each thread  
> > must be prohobited from using the array values, which have been  
> > already  
> > used by other threads.
> > 
> > I was trying to change the code like this:

snip

> @mutex.synchronize {  
> number\_of\_threads.times do |t|  
> the next one gets a chance. You never did anything to alter the  
> @arr that all threads saw.
> 
> I haven’t played with threads for a long time, but unless you change  
> something about @arr, every iterate() will operate once for each  
> element. You run into trouble with the Array#each if you modify the  
> contents of the array inside the block.
> 
> -Rob

If you remove the sleep and initialize with @arr=(1…10000).to\_a you  
see the kind of result you probably want where the @mutex.synchronize  
block is really controlling the access.

-Rob

Rob B. [http://agileconsultingllc.com](http://agileconsultingllc.com)  
removed\_email\_address@domain.invalid
