- PR -

ローカル変数は、絶対に共有されない・・・?

投稿者投稿内容
小野@どっとねっとふぁん
ぬし
会議室デビュー日: 2001/10/30
投稿数: 402
投稿日時: 2003-06-11 14:34
間違ってるわけじゃないんでしょう。たぶん。
というか、私にはJittaさんの文章の意味するところがきちんと読み取れないので
間違ってるかどうかの判断もできない、というのが正確なところです。

#まずASP.NETとVB.NETを混同しない、ってとこからわからない。
 で、急にVBとASPの話になって、VBAになってVBScriptになって。。。
 VBAはともかくVBScriptにModuleなんてないし。。。
べーちゃん
大ベテラン
会議室デビュー日: 2002/07/21
投稿数: 121
投稿日時: 2003-06-11 15:52
>#まずASP.NETとVB.NETを混同しない、ってとこからわからない。

要はModuleをサポートしているのはASP.NET(Webアプリケーション)でなく
VB.NET自体だよということだと思います(WindowsアプリでもModuleは使えますから)。

ところで、
V2000sv01さんのプログラムを見るところ、つまり言わんとされていることは
一つのインスタンスのプログラム内で多数のセッションが確立された時、
あるセッションからモジュール内のTest5が呼び出され、それの処理が
完了する前に(このソースではスレッドがスリープしている間に)、他のセッションが
Test5を呼び出したときにTest5は共有されているからローカル変数を上書きするのでは
ないかということですよね。

答えは...知りません(あぁ、無責任)。

ただ、ローカル変数は基本的に必要な時に作成され、作成されたレベルの処理が終わると
廃棄される仕様になっているので、他との共有がありえないのが原則です。

従って、原則から言うとTest5が呼び出された時点でローカル変数のための領域が
確保され、そのローカル変数の領域を使いスリープする時点で必要な情報をセーブ、
次に他のセッションがTest5を呼び出した時点でまた最初とは別のローカル変数の
ための領域を新たに確保して実行を開始する。そしてスリープする時点で必要な情報を
セーブ、その後最初のセッションが復帰する際にセーブしておいた情報をロードして
(つまりローカル変数の参照先を元の領域にもどして)続きのコードを実行するはずだと
思いますので共有されないはずなんですが、.NETがどう実装しているかは知らないので
明言はできません。
(考え方自体が外れていたらすみません)

それはそうと、基本的にはモジュールはサブルーチンを作るのに用い、
内部にスリープなどの実行中断処理を入れ無いことをお勧めします。
そしたら、ローカル変数が共有されるか心配する必要もないでしょう。


[ メッセージ編集済み 編集者: べーちゃん 編集日時 2003-06-11 15:57 ]
小野@どっとねっとふぁん
ぬし
会議室デビュー日: 2001/10/30
投稿数: 402
投稿日時: 2003-06-11 16:25
引用:

べーちゃんさんの書き込み (2003-06-11 15:52) より:
ただ、ローカル変数は基本的に必要な時に作成され、作成されたレベルの処理が終わると
廃棄される仕様になっているので、他との共有がありえないのが原則です。


Moduleじゃなければそのはずです。
Moduleはそこが特殊だということです。

前に書いたけどメンバーのすべてがstatic宣言されてるのと
同等になるらしいのです。
で、static宣言する、ということはアプリの実行時に
固定のメモリ領域が確保され、その領域が使いまわしされる
ようなイメージになるみたいです。
メソッドもstaticとして宣言されるため、メソッドが
利用するメモリ領域が固定になります。そうすると
その中のローカル変数も実質的に同じメモリ領域を
利用するということになり、結果的に共有されると
いうことらしいです。
伝聞(それもMLでの)なので、らしいばっかですみません(^^;

したがって、ASP.NETじゃなくてもスレッドを利用しているアプリを
作成したとき、Moduleを利用していると思わぬ落とし穴が
待ち受けていそうです。
金星太郎
会議室デビュー日: 2002/12/12
投稿数: 7
お住まい・勤務地: 新潟市
投稿日時: 2003-06-11 19:24
ありがとうございます。みなさん。
小野@EACさん、勘違いの御指摘、助かりました。


なんとなく、わかりました。

・Asp.Netは「サービス」として動くアプリケーションなので、モジュールブロックは特殊である。
・モジュールブロックは特殊なので、使わない方が良い。
・使った場合、ローカル変数が共有されない事は保証されない。
・クラスのスタティック変数はアプリケーション変数と同じ動きをする。

の4点がわかりました。

実は、既にモジュールブロックを作ってしまって、それを参照している部分は
大量に有るのです。本当は、このまま修正無しで、事無きを得たかったのですけど、
全部、クラスに直さないといけないのですね。

とほほです。

なちゃ
ぬし
会議室デビュー日: 2003/06/11
投稿数: 872
投稿日時: 2003-06-11 22:39
引用:

前に書いたけどメンバーのすべてがstatic宣言されてるのと
同等になるらしいのです。
で、static宣言する、ということはアプリの実行時に
固定のメモリ領域が確保され、その領域が使いまわしされる
ようなイメージになるみたいです。



これってメンバの話ですよね?
要はstaticなフィールドやメンバしか定義できない、つまりインスタンスメンバは使えない。
インスタンス化が出来ないので当然そうなると。

引用:

メソッドもstaticとして宣言されるため、メソッドが
利用するメモリ領域が固定になります。そうすると
その中のローカル変数も実質的に同じメモリ領域を
利用するということになり、結果的に共有されると
いうことらしいです。
伝聞(それもMLでの)なので、らしいばっかですみません(^^;



さすがにそれはないと思うんですが。
例えばモジュールのメソッドでは再帰呼び出しが出来ないとか…?

ここで言っている「ローカル変数」というのは、メソッド内部で宣言している
変数の事ですよね?(つまりクラスやモジュールのメンバではない)
ローカル変数はスタックに取られるので共有はされないと思います。
もちろん複数のスレッドが動いている場合でもスタックは独立しています。

ところで最初の話に関してですが、
ローカル変数、インスタンスメンバ、スタティックメンバといった、変数の生存範囲(期間)に関する事と、
メンバのアクセシビリティ(privateとかpublicとか)に関する事は、
独立して考えたほうがよろしいかと思います。

でわ〜
べーちゃん
大ベテラン
会議室デビュー日: 2002/07/21
投稿数: 121
投稿日時: 2003-06-12 03:54
基本的にはローカル変数が共有されるという話はあまり信じられないんですが。
とりあえず、ローカル変数に関する論議はちょっとおいておいて、

>実は、既にモジュールブロックを作ってしまって、それを参照している部分は
>大量に有るのです。本当は、このまま修正無しで、事無きを得たかったのですけど、
>全部、クラスに直さないといけないのですね。

試してないので、間違っているかもしれませんが、
1.モジュールのModuleとEnd Module宣言をClassとEnd Class宣言に書き換える
2.Global.asax内のApplication_Startイベントや、専用のモジュールを作成し
 その中でグローバルなインスタンスを作成し、それをアプリケーション内で
 使いまわす。
もし、現時点でコンパイルエラーがないのであれば1.の変更後に、コンパイラが
該当個所のエラーリストを返してくるはずですので、作業はめんどくさいですが、
すぐに終わると思いますが。

ただ、私が以前発言したように基本的にはプロシージャ(メソッド)内で
スリープとかが入らず完結していれば、スレッドはプロシージャーの
最後まで実行するはずですので現行のままでも問題はないかと思われます。
小野@どっとねっとふぁん
ぬし
会議室デビュー日: 2001/10/30
投稿数: 402
投稿日時: 2003-06-12 07:50
ああ、すみません。
なんか勘違いはいってます。
Public変数、Private変数といったメンバそのものは共有されるけど、
ローカル変数は共有されない、でいいんでしたね。

#うむ、やっぱ仕事でてんぱってるときに深く考えずに
 書き込むのはまずいな(^^;
Jitta
ぬし
会議室デビュー日: 2002/07/05
投稿数: 6267
お住まい・勤務地: 兵庫県・海手
投稿日時: 2003-06-12 08:29
小野@EACさん、わざわざありがとうございました。

その後のポストを見ながら、「そうか、こういう風に書けばいいのか」と、よい勉強になりました。


やっぱり、人に説明するのって難しい・・・と思っているところに「××の件、勉強会やって」って(xx)

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