How to separate objects by thread in ruby's parallel

Asked 2 years ago, Updated 2 years ago, 39 views

I'd like to use ruby's parallel to separate objects for each thread. Is there a good way?

Image

Parallel.each(array, in_threads:10) {|val|

    obj [thisThread] <<val

}

ruby

2022-09-30 15:49

2 Answers

You can retrieve the thread currently running in Thread.current. Wouldn't it be better to put a value in hash with that thread as the key?

require 'parallel'
require'securerandom'
{}.tap {|hash|
  Parallel.each(10.times.to_a, in_threads:5) {|val|
    hash [Thread.current.object_id]||=[]
    hash [Thread.current.object_id] <<val

    # It's hard to understand as a sample if all of them are processed in the same thread.
    # You're explicitly passing your turn to another thread.
    Thread.pass
  }
}
# =>{70296018371880=>[0,9],70296018372240=>[1,3,7],70296018372060=>[2,5],70296018371400=>[4,6,8]}

Also, if you want to keep a value for each thread, you can use thread local variables.

require 'parallel'
require'securerandom'
{}.tap {|hash|
  Parallel.each(10.times.to_a, in_threads:5) {|val|
    Thread.current [:total]||=0
    Thread.current [:total]+=val
    hash [Thread.current.object_id] = Thread.current [:total]

    # It's hard to understand as a sample if all of them are processed in the same thread.
    # You're explicitly passing your turn to another thread.
    Thread.pass
  }
}
# =>{70296003558440=>11,70296003558620=>5,70296003558880=>16,70296003558120=>6,70296003557940=>7}

However, data structures such as Hash originally included in Ruby in hash are not thread safe, so you might want to use ThreadSafe::Hash in libraries such as thread_safe.

require 'parallel'
require 'thread_safe'
require'securerandom'
ThreadSafe::Hash.new.tap {|hash|
  Parallel.each(10.times.to_a, in_threads:5) {|val|
    Thread.current [:total]||=0
    Thread.current [:total]+=val
    hash [Thread.current.object_id] = Thread.current [:total]

    # It's hard to understand as a sample if all of them are processed in the same thread.
    # You're explicitly passing your turn to another thread.
    Thread.pass
  }
}
# =>{70280165348680=>13,70280165348480=>6,70280165348340=>16,70280165348200=>10}


2022-09-30 15:49

require'pp'
require 'parallel'

val=[].tap {|a|
  (1..100).each {|i|
    a<<i
  }
}

Parallel.each(val.each_slice(10), :in_threads=>1) {|split_val|
  pp split_val
}

I'm not sure, but do you mean you want to do something like this?


2022-09-30 15:49

If you have any answers or tips


© 2024 OneMinuteCode. All rights reserved.