- PR -

staticメソッド内でスレッド間共有されるものは?

1
投稿者投稿内容
ryuuji
ベテラン
会議室デビュー日: 2003/07/10
投稿数: 53
お住まい・勤務地: 東京都
投稿日時: 2007-02-28 14:14
いつもお世話になっております。

マルチスレッド下でstaticメソッドが呼び出された場合、staticメソッドの引数、メソッド内のローカル変数など全てスレッド間で共有されるのでしょうか?

staticでないメソッドの場合、メソッドの引数、メソッド内のローカル変数は呼び出し元スレッドの持ち物(←これをコンテキストと呼ぶ?)としてOSがスレッドを切り替える度に個々にセーブ/ロードされる(どこにセーブされるのか不明)ため複数のスレッドが同時にそのメソッドを呼び出してもメソッドの引数、メソッド内のローカル変数などはスレッド間で共有されない認識です。

しかしOS関連の書籍を読んでいたところメソッドの引数はスレッド毎に持つスタックに積まれるとありました。ということはスレッド間で共有されるのはメソッド内のローカル変数のみでメソッドの引数は呼び出し元スレッドの持ち物なのではないか、と思いました。

ただ.NETのクラスインスタンスは原則ヒープに確保されると記憶していたので、そもそも「メソッドの引数はスタックに積まれる」というのはもっと低レベルな話で.NET上では全然別な管理をしているのかも知れないと思っています。このような点はどのような文献なりドキュメントを読めば分かるのでしょうか?

MSDNの静的メンバの辺りを読んでみたのですが答えを見つけられませんでした。
http://msdn2.microsoft.com/ja-jp/library/98f28cdx(VS.80).aspx
http://msdn2.microsoft.com/ja-jp/library/79b3xss3(VS.80).aspx
渋木宏明(ひどり)
ぬし
会議室デビュー日: 2004/01/14
投稿数: 1155
お住まい・勤務地: 東京
投稿日時: 2007-02-28 15:33
引用:

マルチスレッド下でstaticメソッドが呼び出された場合、staticメソッドの引数、メソッド内のローカル変数など全てスレッド間で共有されるのでしょうか?



原則、されません。

引用:

しかしOS関連の書籍を読んでいたところメソッドの引数はスレッド毎に持つスタックに積まれるとありました。ということはスレッド間で共有されるのはメソッド内のローカル変数のみでメソッドの引数は呼び出し元スレッドの持ち物なのではないか、と思いました。



静的メソッドの引数とスレッドプロシージャに与えるパラメータ辺りがごっちゃになってませんか?
静的メソッド=スレッドプロシージャではありません。

前項で「原則、されません」と回答しましたが、スレッドプロシージャに与えるパラメータ(に含まれたオブジェクトインスタンス)は、コード記述によっては、新たに起動されたワーカースレッドとそのスレッドを起動したスレッド間で共有されます。
ryuuji
ベテラン
会議室デビュー日: 2003/07/10
投稿数: 53
お住まい・勤務地: 東京都
投稿日時: 2007-03-01 23:43
返答ありがとうございます。

> 原則、されません。
>静的メソッドの引数とスレッドプロシージャに与えるパラメータ辺りがごっちゃになっ
>てませんか?
Cのグローバル変数などとごちゃ混ぜにして考えてしまっていたようです。
Cでも関数の引数やローカル変数は、その関数の呼び出し元スレッドの持ち物
だったような気がしてきました。

そもそもstatic変数やグローバル変数とstaticメソッドを一緒に考えるのが間違いなんでしょうか?
渋木宏明(ひどり)
ぬし
会議室デビュー日: 2004/01/14
投稿数: 1155
お住まい・勤務地: 東京
投稿日時: 2007-03-02 09:59
引用:

Cでも関数の引数やローカル変数は、その関数の呼び出し元スレッドの持ち物
だったような気がしてきました。



「スレッドの持ち物」という視点がよくないんじゃないでしょうか。

スレッドは、そのスレッドに関連付けられたコンテキストに所属するコード(=アセンブラの知識があるなら、コンテキストが保持しているPCの値が指し示すコードと考えればよいでしょう)を逐次実行するだけのものです。

スレッドは、コードを実行する過程で、コンテキストに格納されている各種の情報を利用します。

コンテキストにはスタックも含まれるので、多くの実装でスタック上に領域が確保されるローカル変数もコンテキストに所属しているもの(=他のスレッドからは見えない)と考ることができます。

「グローバル変数」はコンテキストではなく、プロセス空間内に配置されるので、スレッド間で共有されます。

スレッドとスレッドコンテキストの関連付けは実行開始時に決定して「そのまんま」であることが多いですが、その結びつきは絶対的なものではありません。

1つのスレッドに対して複数のスレッドを定期的に切り替えて与えることで、原始的なマルチタスクが実現できたりします。

引用:

そもそもstatic変数やグローバル変数とstaticメソッドを一緒に考えるのが間違いなんでしょうか?



ローカル変数がどのように管理されているのかの理解があやふやな上に、「static」というキーワードに惑わされているフシがありますね。

static の訳語は「共有」ではなく「静的」です。
「static メソッド」は「静的メソッド」であり、この場合の「静的」は「特定のインスタンスに所属しないこと」を示しています。

「静的メソッド」だろうと「インスタンスメソッド」だろうと、メソッドはメソッドです。

同様にメソッド中で使用される「ローカル変数」も、「静的メソッド」中でも「インスタンスメソッド」中でも、全く同じ仕組みで管理されます。


[ メッセージ編集済み 編集者: 渋木宏明(ひどり) 編集日時 2007-03-02 10:14 ]
ryuuji
ベテラン
会議室デビュー日: 2003/07/10
投稿数: 53
お住まい・勤務地: 東京都
投稿日時: 2007-03-08 13:39
渋木様

返信ありがとうございました。
今頃の返信で申し訳ないです。

そもそもC言語のstatic、グローバル変数も良く理解していなかったことにも気づきました。丁寧なご説明ありがとうございました。staticかどうかでスレッドが属するコンテキストに含まれるものが変わるわけではない、と理解しました。

(Cのstaticやグローバルについては以下のURLが理解するのに役立ちました)
http://www.pro.or.jp/~fuji/mybooks/cpro/cpro.4.5.1.html

ありがとうございました。
1

スキルアップ/キャリアアップ(JOB@IT)