Wizard In The Market
システムトレードの魔術師

*

絶対ダメ! マルチスレッドでの共通変数のインクリメント演算

公開日: : Python , , , , , ,

Hack de Overheid - Apps voor Amsterdam

Photo by Sebastiaan ter Burg

デバッグ中の発見

とあるマルチスレッドプログラムをPythonで書いていた際に遭遇した誤使用です。C/C++等の言語を使った場合には起こらない仕様なので、知っておくと役立つ時がくるはずです。これはPythonだけでなく、Rubyでも同様のことが起こるので、Rubyistさんも是非気をつけていただければと思います。

@ahaha_traderさんのご指摘により、C/C++でも同様のことが発生することを教えていただきました・・・。不勉強をお詫び申し上げます。

このブログを見ているような方々だとバグが生じる実際のコードと、結果をまずお見せしたほうが良いと思うので、サンプル用に作ったコードがこちらです。

バグが生じるソースコード

やっている内容は、12個のスレッドを使って self.increment_count + 1 を12,000回繰り返すという単純処理です。

実行結果

本来、12*1,000の12,000を表示させたかったはずのこのコードなのですが、残念ながら29の違いが生じています。なぜこれが生じてしまうのでしょうか。

動作不良の理由

C/C++など、正式なインクリメントが適応されているような言語ですと、マルチスレッドで行っても、確実にプロセッサレベルで正確にインクリメント処理が行われるので問題がありません。

ですが、PythonやRubyのインクリメント処理は、C/C++で使用されるようなインクリメント処理とはまったく異なります。PythonやRubyの場合のインクリメントの記述自体は、インクリメントっぽく書かれていますが、実際に行われているのは以下の処理です。

ということは、increment_count + 1 の演算が行われた後の結果のPython/Rubyオブジェクトにincrement_countの参照が適応されます。簡単に言うと、演算と結果の格納が2つの処理になってしまっているのです。

この場合、マルチスレッドにて、increment_count + 1 の演算がポインタの割り当てより前に他のスレッドにて同時に行われてしまうというケースが生じます。それが、今回の検証の場合 29/12,000 の割合で生じてしまっていたのですね。

参考URL

誤使用の回避方法

回避する方法は、Queue.Queueクラスを使い、putされた個数を取得するという方法が簡単で便利です(12,000回もカウントするのには実用的ではないけれど)。他にもthreading.Lockを使う方法もありますが、マルチスレッドの利点が減ってしまうかもですね。

なかなかデバッグしにくい内容で手こずりましたが、バグの原因が特定できると納得の行く結果となりました。みなさんもお気をつけ下さいね!

にほんブログ村 為替ブログへ 
Fx-Kirin

About Fx-Kirin

2009年10月にFXを開始、翌年2010年5月から脱サラをしてFX業界に専念。 2012年10月頃から本格的に勝ち始め、一月で資産を倍にする、2年半月間負けなし等、安定した収支で2013年11月に生涯FX収支が1億を超える。 投資スタイルはシステムトレード。プログラミングの知識がほぼない状態から、独学で自分がしたいと思うことであればほぼ実現することが可能なレベルまで成長。好きな言語はRuby, Python。必要となればC++からVBA、Pascal等なんでも行う。MT4/MT5のプログラミングも得意。 2011年にはFXで稼いだ資金をもとにシンガポールに移住し、留学も兼ねて起業をチャレンジするほど、ビジネスを興すことに熱意がある。国内の業者を主に使い始めたことから、2012年に帰国。零細株式会社経営中。

Adsense

  • このエントリーをはてなブックマークに追加
  • Pocket
  • 54 follow us in feedly

関連記事

no image

stop automatically closeing vim-ipython output with jedi-vim

Even though I commented out the following code in vim_ipytho

記事を読む

Pythonのsocketでプロセス間通信をして価格データ等を送信する

どうも、お久しぶりです。キリンです。 取り敢えず1ヶ月ほど、連続でブログの更新を続けてみたのですが、そ

記事を読む

no image

JAVA の SHA1 Digestの作り方

>>> import base64 >>> import hashlib >>> base64.b64encode(

記事を読む

no image

vim-ipythonをWindows 7 x64で使うとR6034 が出る件

個人的なただの忘備録。 Visual Studioのコマンドプロンプトから実行すること。 http://st

記事を読む

VimでPythonのIDE 環境を一から構築する

追記 これ見ておいたほうがいいかも。 Vimを最強のPython開発環境にする2 - Λlisue's blog

記事を読む

Python x64 & MinGW64 環境の構築

流石に詰まりまくったのでまとめることにする。 MSYS2 をインストール 個人的にこれからメインで使いたいと思っ

記事を読む

CPP extension vs Cython vs CPython on calculating the mean of numpy array

I'd like to get any feedback to make cython faster like

記事を読む

Python の超お手軽のネットワーク分散コンピューティングライブラリSCOOP

SCOOPとは ssh とPython の設定を適切にするだけで、簡単にネットワーク間での分散処理が実行できる。

記事を読む

Quantopian の pyfolio を単利運用に対応させる。

pyfolio は どんなデータを入れても複利運用として計算してしまうので、人によっては望まない検証方法だったりし

記事を読む

vim-slime を使って VIM の内容をコンソールに送信

この記事はVim Advent Calendar 2016の20日目の記事です。 選択行の内容をコンソールに送信

記事を読む

Message

メールアドレスが公開されることはありません。 * が付いている欄は必須項目です

Adsense

システムトレードを始める前に知っておきたかったこと

今日の勉強会で発表してきました。nbviewer に共有しておきます。 システムトレードを始め

chmod で やらかしてしまったときの対処法

メモ書きです。 find | xargs とかを普通にやってしまうと、すぐに argument

AMD Ryzen & Nvidia GTX 1080 BTO PC 構成・組立と Ubuntu インストール

まだググっても、構成例とか出てないので参考になるんじゃないかなと。機械学習用ですが、全然ゲーム用

Windows のデスクトップアプリをSSHクライアントから再起動する

シェルスプリクト一発で、システムトレードの設定を一括で更新して、MT4を再起動したいとかそういう

UX21A のディスプレイが壊れたので修理

UX21A のディスプレイがぶっ壊れた。 画面にラインが入ったり、ディスプレイが揺れたりするよ

→もっと見る

PAGE TOP ↑