fc2ブログ

変数のスコープを極力狭くする理由

 変数のスコープを極力狭くするべきなのは、並行プログラミングに限った話ではありません。実務を経験している人は、大概同じ事を考えますし、情報隠蔽の原則として有名な事ですが、その原則を破る事も出来ます。しかし、並行プログラミングに於いては、破る事が出来ない原則なので理由を詳しく書きます。
 並行プログラミングをしていなくとも、グローバル変数(大域変数)を多用すると、スパゲッティプログラムになりやすく、バグを生む可能性が高くなります。しかし、余分な労力をつぎ込めば、何とか動作できます。一方、並行プログラミングの場合、正常に動作させる事自体が困難になります。その理由は、処理結果が予想できなくなり、それを防ぐために同期処理を使用すると、デッドロックや優先順位逆転問題などが発生する可能性があるからです。つまり、スコープが広い変数を使う事のコストとリスクが高すぎるのです。
 その理由から、理想的には変数は局所的(ローカル)であるべきです。ローカル変数を使用すると、始めから値の不整合が起こりません。それ故、同期処理の必要もなくなります。では、何故その様な事が起こるかというと、ローカル変数をアセンブラレベルで考えれば分かります。
 順を追って説明します。グローバル変数は、プロセスごとに決められたメモリアドレスの範囲に配置されますので、同じプロセスに属する個々のスレッドがアクセスできます。一方ローカル変数は、スレッドごとに持つスタック内に保持するので、他のスレッドの影響を受けません
 スレッドがスタックを持つ理由は、各スレッドは通常異なる手続きを呼び出し、異なる実行履歴を持つからです。関数呼び出しを実現するには、呼び出し前にいた場所(アドレス)と引数の値をスタックという形で保持しなくてはなりません。また、ローカル変数の値もスレッドごとに違いますので、スタックに保存しなくてはなりません。もし各スレッドがスタックを持たなければ、必要な情報をレジスタに保存する必要がありますが、レジスタの数は限られていますので、非常に少ない数のスレッドしか実行出来ず、ローカル変数の数も制限される事になります。それでは不都合が多すぎるので、スレッドごとのスタックに保存される形で実現されています。
 ローカル変数が使用できない場合は、スレッドローカルストレージ(TLS)を使用します。スレッドが持つスタック内の、決められた場所に変数を保存する事により、他のスレッドの干渉を防ぐ事が出来ます。この変数の名前は定められておらず、プライベート大域変数、TLS内に保持された変数・・・等と、文脈に沿って表現されています。
スポンサーサイト



テーマ : プログラミング
ジャンル : コンピュータ

コメントの投稿

非公開コメント

プロフィール

インドリ

Author:インドリ
みなさん、はじめまして、
コンニチハ。

ボクは、無限の夢(infinity dream)を持つネタ好きな虹色の鳥インドリ(in dre)です。
色々な情報処理技術を啄ばむから楽しみにしてね。

http://twitter.com/indori
は別人による嫌がらせ行為です。
私とは関係ないので注意して下さい。
次はなりすましブログなどをするかもしれませんが、ここ以外でブログをするつもりがないので、ここ以外にインドリのブログがあったとしても無視してください。


何度言っても分からない人がいるので、ここにコメント欄へ書き込むときの注意事項を書きます。


一、社会人としてのマナーをわきまえましょう。
一、妄想に基づく書き込みを止めてください。
一、暴言の類は書かないで下さい。
一、某誹謗中傷サイトの書き込みは彼らの妄想に基づく書き込みですから無視して、ここへ書き込まないで下さい。
一、コメント書く前に他のコメントよく読んでから行って下さい。
一、言いがかかり等の行為を禁止します。
一、その他常識的に考えて迷惑なコメントはしないで下さい。


以上のルールを守れない人のコメントは削除します。



利用上の注意
ここに紹介してある文章およびプログラムコードは正確であるように心がけておりますが、内容を保証するものではありません。当サイトの内容によって生じた損害については、一切の責任を負いませんので御了承ください。


執筆したCodeZineの記事


【VB.NETで仮想CPUを作ろう】

  1. VB.NETで仮想CPUを作ろう
  2. レジスタの実装
  3. 仮想CPUのGUI化
  4. テストドライバの改良
  5. CPUの基礎動作の実装
  6. MOV命令の実装
  7. ADD命令実装
  8. SUB命令実装
  9. INC命令&DEC命令の実装と命令長
  10. MLU命令の実装とModR/Mについて
  11. DIV命令の実装とイベント設計について
  12. 機械語駆動式 関数電卓を作ろう!
  13. 機械語駆動式 関数電卓を作ろう! 解答編(前半)
  14. 機械語駆動式 関数電卓を作ろう! 解答編(後半)


【仮想ネットワーク実装でTCP/IPを学ぼう】
  1. TCP/IPの基礎と勘所
  2. ネットワークアクセス層の勘所
  3. インターネット層の勘所
  4. トランスポート層の勘所
  5. アプリケーション層の勘所
  6. セキュリティの基礎と仮想ネットワークの仕様
  7. GDI+と独自プロトコルの定義



【並列化】
インテル Parallel Studioを使って並列化プログラミングを試してみた
並列プログラミングの効率的なデバッグを実現する「Parallel Inspector」


【TBBシリーズ】
  1. インテル スレッディング・ビルディング・ブロックの概要
  2. インテルTBBから学ぶループの並列化
  3. スレッドセーフとインテルTBBのコンテナ
  4. インテルTBBのスレッドクラス


【OpenMPシリーズ】
  1. OpenMPの基礎構文
  2. OpenMPの実行時ライブラリと並列ループ
  3. OpenMPのメモリモデルとfork- joinモデル

最近の記事
最近のコメント
月別アーカイブ
カテゴリ
Ada (9)
COBOL (5)
C (9)
C++ (11)
C# (370)
D (25)
Java (8)
Perl (1)
Ruby (14)
PHP (2)
Boo (2)
Cobra (2)
LISP (6)
F# (33)
HTML (0)
XHTML (0)
CSS (0)
XML (0)
XSLT (0)
Scala (4)
WPF (0)
WF (2)
WCF (0)
LINQ (4)
MONO (5)
Linux (0)
MySQL (0)
ブログ内検索
リンク
最近のトラックバック
RSSフィード
ブロとも申請フォーム

この人とブロともになる

QRコード
FC2カウンター