私は、操作が必要な行のリストを持つデータベースを持っています。私はルビーとDataMapperのを使用していますが、実際に私はこれは私が使用している正確な実装に固有ではない一般的なプログラミングの問題だと思う...複数のワーカースレッドが同じデータベースで動作している - 正しく動作させるには?
id remaining delivered locked
============================================
1 10 24 f
2 6 0 f
3 0 14 f
:それは次のようになります私は、この(擬似ルビー・コード)のような何かを行うワーカースレッドの束作成しています:もちろん
while true do
t = any_row_in_database_where_remaining_greater_than_zero_and_unlocked
t.lock # update database to set locked = true
t.do_some_stuff
t.delivered += 1
t.remaining -= 1
t.unlock
end
、問題があるが、これらのスレッドは互いに競合し、全体のことは本当にスレッドではありません安全。 whileループの最初の行は、ロックされる機会を得る前に、同じ行を複数のスレッドで簡単に引き出すことができます。
1つのスレッドが同時に1つの行で作業していることを確認する必要があります。
これを行うにはどのような方法が最適ですか?
Rubyにはグローバルインタプリタロックがあるので、一度に1つのスレッドしか動作しないことはすでに保証されています。 – robbrit
これは正しいとは思わない...スレッドの最初の行は複数のスレッドで実行できる.. – MikeC8
ああ、そうだね、Ruby 1.9では競合条件がある可能性がある。なぜ、一度に1つの行を引っ張るのではなく、N個の行をプルして、Nをスレッドの数とし、各スレッドを返された行の1つで操作させますか?それから、すべてのスレッドが完了したら、完了するまで別のNを引きます。 – robbrit