ようこそ ゲスト さん、新規登録(無料)して気になる疑問を解決しませんか?

質問

QNo.4004300 DLLはアドレスを共有する?
質問者:jm4cvp  CでWindowsプログラミングの勉強をしています.そこでDLLについての質問なのですが,ある本で「DLLは複数のプログラムが共有し,ひとつのDLLはひとつしかメモリ上に配置されない」という文章を読みました.プログラムはDLLの配置されてあるアドレスを元に,DLL内の関数を実行するのだと考えれば納得はいきましたが,よく考えたらおかしいと思いました.
 それは「変数,関数」の取り扱いはどうなるのか,ということです.C言語で物理メモリアドレスを見る方法がわからないので何とも言えませんが,試しに,DLL内に次のような関数MyFunctionを用意し,このDLLを取り込むプログラムを同時に2つ走らせ,MyFunctionを何度も呼んでDll1_Variableの値を増加させていきました.

LIBSPEC int MyFunction(LPCWSTR str)
{
static int Dll1_Variable=0;
Dll1_Variable++;
_tprintf(_T("%d\n"),Dll1_Variable);
return 0;
}

 もしDLLが共有されているのならば,Dll1_Variableの値は2つのプログラムから同時に更新されると思うのですが,実際には2つのプログラム上でまったく独立(つまり各プログラムごとに1,2,3,...というように)増加していきました.こうなるとDLLって本当に共有されているのかという,不信感が出てきてしまいます.

 なんだか重大な勘違いをしている気がしてなりませんが,上記のプログラムがなぜ独立に変数が増加していくのか,「DLLが共有される」というのは実際にはどういう仕組みになっているのか,ご存知の方がいらっしゃったらご教授ください.わかりにくい質問ですみません.よろしくお願いします.
困り度:
  • 困っています
質問投稿日時:
08/05/07 15:07
この質問に対する回答は締め切られました。

回答

ANo.3 >スレッドの場合も個々にデータを保持しているのでしょうか.

これは、特に指定しない限りは、同じプロセスに属するスレッドであれば
全く同じデータを共有します。
なので、

> スレッドの場合は何か特別な事情が生じてくることはあるのでしょうか.

まさしくこのとおりです。

スレッド ローカル ストレージ (TLS: Thread Local Storage)
http://msdn.microsoft.com/ja-jp/library/6yh4a9k1.aspx
回答者:sakusaker7
種類:回答
どんな人:一般人
自信:参考意見
回答日時:
08/05/07 16:17
この回答へのお礼なるほど,スレッドの場合は気をつけなければならないということですね.よく理解できました.ありがとうございます.

回答良回答10pt

ANo.2 プログラムがロードされる領域と変数が使う領域は別物だからです。
回答者:wolf03
種類:アドバイス
どんな人:一般人
自信:参考意見
回答日時:
08/05/07 15:48
この回答へのお礼そうですよね.単純な事実にまったく気がつきませんでした.

ところで,これに共有に関してさらに疑問に思ったこととして,マルチスレッドの状況で複数のスレッドがDLLを共有するとどうなるのでしょう?スレッドは確かメモリ空間を共有するという話を聞きましたが,スレッドの場合も個々にデータを保持しているのでしょうか.

「スレッドセーフ」という言葉もあることですし,スレッドの場合は何か特別な事情が生じてくることはあるのでしょうか.

回答良回答20pt

ANo.1 Win32(要するにNTとか、95以降の奴)ではコードの共有をどのようにしていたか(していないか)は
ちょっと忘れてしまいましたが、データ部分については、特に指定しない限りは
プロセスごとに独立した空間が割り当てられます。

ですので質問の例にあるように、カウンタは独立して増えることになります。

DLL 内のデータをアプリケーションまたはほかの DLL と共有する方法
http://msdn.microsoft.com/ja-jp/library/h90dkhs0.aspx

参考までに、Win16(Windows 3.1とか)の場合は、
プログラムコードはまるっきり共有されますが、
データ部分はこれもプロセスごとになります。
#コード→CSレジスタで示す領域
#データ→DSレジスタで示す領域
回答者:sakusaker7
種類:回答
どんな人:一般人
自信:参考意見
回答日時:
08/05/07 15:46
この回答へのお礼なるほど,コードの共有は行ってもデータについては個々に持っているということですね.よくわかりました.ありがとうございます.