Asp Forum
Home
|
Login
|
Register
|
Search
Forums
>
comp.lang.ruby
Threads and synchronized access to an array
Bob Bobrov
6/18/2008 9:23:00 PM
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}
--
Posted via
http://www.ruby-...
.
3 Answers
Rob Biedenharn
6/18/2008 10:11:00 PM
0
On Jun 18, 2008, at 5:23 PM, Bob Bobrov wrote:
> 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}
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 Biedenharn
http://agileconsult...
Rob@AgileConsultingLLC.com
Rob Biedenharn
6/18/2008 10:16:00 PM
0
On Jun 18, 2008, at 6:11 PM, Rob Biedenharn 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
> 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
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 Biedenharn
http://agileconsult...
Rob@AgileConsultingLLC.com
Bob Bobrov
6/19/2008 10:55:00 AM
0
Rob Biedenharn 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!
--
Posted via
http://www.ruby-...
.
Servizio di avviso nuovi messaggi
Ricevi direttamente nella tua mail i nuovi messaggi per
Threads and synchronized access to an array
Inserendo la tua e-mail nella casella sotto, riceverai un avviso tramite posta elettronica ogni volta che il motore di ricerca troverà un nuovo messaggio per te
Il servizio è completamente GRATUITO!
x
Login to ForumsZone
Login with Google
Login with E-Mail & Password