無料で使えるシステムトレードフレームワーク「Jiji」 をリリースしました!

・OANDA Trade APIを利用した、オープンソースのシステムトレードフレームワークです。
・自分だけの取引アルゴリズムで、誰でも、いますぐ、かんたんに、自動取引を開始できます。

スレッドごとに固有のデータを管理したい。

Rubyのスレッドは、スレッド固有のデータを持つことができます。Thread.currentで現在実行中のスレッドが取得できるので、これと組み合わせてJavaThreadLocalのように使うことができます。

ts = []
3.times{|i|
  ts << Thread.fork(i) {|i|

    #
    # スレッド固有のデータを使う。
    # Thread.current[:count]はスレッドごとに確保されるので、
    # 生成した3つのスレッドで値が共有されることはない。
    #
    Thread.current[:count] = 0
    10.times {|j|
      Thread.current[:count] += 1
      puts i.to_s << ":" << Thread.current[:count].to_s

      sleep rand * 0.1
    }
  }
}

ts.each {|t| t.join }

実行結果です。

0:1
1:1
2:1
2:2
0:2
2:3
1:2
0:3
2:4
0:4
0:5
1:3
1:4
0:6
2:5
2:6
1:5
0:7
2:7
1:6
0:8
0:9
1:7
0:10
1:8
2:8
1:9
2:9
1:10
2:10

ただし、ThreadLocalと違って、他のスレッドからも領域にアクセス可能です。なので別スレッドからも使う場合は排他制御が必要です。

# スレッド / Thread.current[:count]の値をインクリメント。
t = Thread.fork {
  Thread.current[:count] = 0
  100.times {|j|
    count = Thread.current[:count]

    # この辺で運悪くスレッドが切り替わると、
    # hread.current[:count]が1つづつインクリメントされない場合が起こる。
    count += 1

    Thread.current[:count] = count
    puts "thread:" << Thread.current[:count].to_s
  }
}

# メインスレッドでもt[:count]を更新
100.times {|j|
  count = t[:count]
  count += 1
  t[:count] = count
  puts "main:" << t[:count].to_s
}
t.join

実行結果です。★のあたりでメインスレッドで行われたはずの更新がすっ飛ばされています。

...
thread:10
thread:11
thread:12
main:13
main:14
main:15
main:16
main:17
main:18
main:19
main:20
main:21
main:22
main:23
main:24
main:25
main:26
main:27
main:28
main:29
main:30
main:31
main:32
main:33
main:34
main:35
thread:13 ★
thread:14
thread:15
thread:16
thread:17
thread:18
thread:19
thread:20
...