質問: そんなことはやってみればわかるはずではありますが、基本的なことなのでその仕組みを教えていただきたく質問します. ### 前提条件 * C++で複数のモジュールを有するプログラムを作成したとします.最終的には、このプログラムはコマンドラインで実行されます.ターゲットのOSはWindowsとLinuxです. * このメインのプログラムから呼び出される複数のサブモジュールがあります.Windowsでは.dllとしてビルドされ、Linuxでは.soとしてビルドされます. * このうち「あるサブモジュール」は、環境変数から値を取得して自身 ***のstaticデータ*** を初期化します.値では抽象的ですので具体的に言うとフォントの格納されているパスです.なのでWindowsでは、C:\Windows\Fontsが典型的です. * Windowsでは、DOS窓を2つ開いて別々の環境変数を与えて、このメインのプログラムのコマンドラインを各々起動した場合、該当のサブモジュールの.dll ***のstaticデータ*** は、別々の初期化をされるでしょう..dllはプロセス間では共有されないからです. ### 聞きたい点 しかし、Linuxの.soの場合がどうなるのか、知識不足でよくわかりません.Linuxの.so(Shared Object)は、例えば以下の説明を参照すると、異なるバージョンのライブラリを共存させる仕組みとしては有効に思えます. 共有ライブラリ > > 共有ライブラリは、プログラム起動時にロードされるライブラリです。 共有ライブラリが適切にインストールされると、その後に起動される全てのプログラムは、自動的にその新しい共有ライブラリを使うことになります。 実際には、これよりもはるかに柔軟で洗練されています。なぜなら、Linux における共有ライブラリの実現方法のおかげで、次のことが可能となるからです。 > > > * ライブラリを更新しながらも、そのライブラリの古くて後方互換性のないバージョンを使いたいというプログラムを、引き続きサポートすることができる > * 特定のプログラムを実行するとき、特定のライブラリ、もしくはライブラリ内の特定の関数でさえもオーバーライドすることができる > * 既存のライブラリを使用してプログラムが動いている間にも、これら全てをおこなうことができる > > > しかし同じバージョンの.soが、あるターミナルウィンドウで起動したメインのプログラムの起動によりシステム上にロードされた場合、別のターミナルウィンドウで異なる環境変数を与えてメインのプログラムを起動すれば、環境変数を参照して自身 ***のstaticデータ*** を初期化するこの「あるサブモジュール」の.soはどのように動作するのでしょうか?たぶん答えは2つしかありません. 1. Windowsのようにプロセスに固有に.soのプログラムのインスタンスが生成され ***別々のstaticデータが初期化され*** る. 2. .soすなわちShared Objectなのだから、すでにLinuxのシステム上にロード&初期化されている.so ***のstaticデータ*** がプロセス間で共有されて使用される.つまり異なる環境変数を与えてもあとで起動した方の ***staticデータの初期化の*** 意図は達成されない. 上記どのようになるのか、教えていただければと考えます. ※ 普段あまりOSに近い仕事をやっておりませんので、用語の使い方など不適切なこともあると思いますがよろしくお願いいたします. [追記 2020-10-11] とかくこの手の質問をするときに、コメントや回答をいただいてから、自分の質問の仕方の不正確さに気が付きます、.dllや.so固有のstaticデータの事しか考えておりませんでした.すでに回答いただいた方には大変申し訳ありませんが、斜体+太字で本来ちゃんと記述をすべきであった箇所を追記いたしました. 以上
回答: 何がわからないのかオイラにわからないので一般論です 共有ライブラリが共有するのは共有できる(=書き変わらない)ところだけ、すなわち「コード」です (x86 で言えば `CS` に関連するところ) 「データ」は共有されません。スレッドごとにスタックが作られるのと同様、プロセスごとにデータ領域は別に作られます (そのデータが EXE 由来であろうと DLL/so 由来であろうと) 。 ----shared.c---- ``` int global_variable; // データはプロセスごとに違うものが作られる void set_func(int val) { global_variable=val; } // コードは共有される ``` `static` データもデータのうちなのでプロセスごとに別々に作られる状況に違いはありません。考え方としては、データ領域は( `static` データ領域を含むし `malloc()` が使うヒープ領域も含む)プロセスごとに存在します。 `EXE` 専用のデータ領域と `DLL` 専用のデータ領域というものがあるわけではありません。 [linux](/questions/tagged/linux "'linux' のタグが付いた質問を表示") でも状況は同じく `a.out` 専用のデータ領域と `libhoge.so` 専用のデータ領域があるわけではありません。 # 同じ `DLL` を使うと異なる `EXE` 間でデータ共有できるよう特別に作ればそこだけ話は別