

rubyのparallelを使って、スレッドごとにオブジェクトを分けて処理したいのですが、良い方法はありますか?

イメージ

[code]

    Parallel.each(array, in_threads: 10) {|val|
    
        obj[thisThread] << val
    
    }
    
[/code]


CC BY-SA 3.0
2014-12-18T07:38:58.543
2008
2014-12-19T21:29:47.973
4947
question
ruby
rubyのparallelでスレッドごとにオブジェクトを分ける方法


[Thread.current](http://docs.ruby-
lang.org/ja/2.1.0/method/Thread/s/current.html)で現在実行中のスレッドを取得できます。
そのスレッドをキーにして`hash`に値をいれるといいのではないでしょうか。

[code]

    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
    
        # 全部同じスレッドで処理されるとサンプルとして分かりづらいので
        # 明示的に他のスレッドに順番を譲っています
        Thread.pass
      }
    }
    # => {70296018371880=>[0, 9], 70296018372240=>[1, 3, 7], 70296018372060=>[2, 5], 70296018371400=>[4, 6, 8]}
    
[/code]

またスレッドごとに値を保持したいならスレッドローカル変数などを使うといいと思います。

[code]

    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]
    
        # 全部同じスレッドで処理されるとサンプルとして分かりづらいので
        # 明示的に他のスレッドに順番を譲っています
        Thread.pass
      }
    }
    # => {70296003558440=>11, 70296003558620=>5, 70296003558880=>16, 70296003558120=>6, 70296003557940=>7}
    
[/code]

ただし、`hash`にRubyに元から入っている`Hash`などのデータ構造はスレッドセーフではないので[thread_safe](https://github.com/ruby-
concurrency/thread_safe)などのライブラリに入っている`ThreadSafe::Hash`などをあわせて使うとよいのではないでしょうか。

[code]

    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]
    
        # 全部同じスレッドで処理されるとサンプルとして分かりづらいので
        # 明示的に他のスレッドに順番を譲っています
        Thread.pass
      }
    }
    # => {70280165348680=>13, 70280165348480=>6, 70280165348340=>16, 70280165348200=>10}
    
[/code]

## 参考

  * [Ruby core classes aren't thread-safe](http://www.jstorimer.com/pages/ruby-core-classes-arent-thread-safe)
  * [Concurrency in jruby](https://github.com/jruby/jruby/wiki/Concurrency-in-jruby#core-classes-and-standard-library)


CC BY-SA 3.0
2014-12-18T08:33:13.777
2017
2014-12-18T08:33:13.777
2599
2008
answer

[code]

    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
    }
    
[/code]

よくわからないんですがこういうことがしたいということでしょうか


CC BY-SA 3.0
2014-12-19T21:29:47.973
2172
2014-12-19T21:29:47.973
5313
2008
answer