インスタンス(実体)の生成について

[戻る]
YouS 2007/07/10(火) 09:39:32
スレッドセーフとインスタンスについて教えてください。

windows2K上のVC++6.0であるライブラリを追加しました。
そして、このライブラリの関数をラップするクラスを作成
しました。(ラップと言う言葉の定義は、メンバ関数から
このライブラリをコールと言う認識でいいんでしょうか?)
このライブラリに含まれている関数は、
スレッドセーフではありません。
^^^^^^^^^^^^^^^^^^^^^^^^^^
プログラムはGUIとは別でスレッドが2つ
走ります。そして各々のスレッドで上記の
クラスを使いたいのです。

ここで質問なのですが、
2つのスレッドをスレッドA、スレッドBとした場合、
それぞれのスレッド上でクラスを宣言すれば、
ライブラリの関数に関しては問題なく動くもの
なのでしょうか?
仮にGUIから各スレッドの呼び出しの際にクラスの
ポインタを渡した場合は当然インスタンスは1つですから
スレッドA、Bで同時にライブラリの関数が呼ばれた場合、
予測出来ない不具合が発生するのは理解できます。
しかし各クラスで独立してクラスを宣言している場合でも
同様の事が起こりうるのでしょうか?
後者の方法でスレッドをデバッグすると、VCが突然
固まって強制終了せざるを得ない状態になってしまいます。
これがそのせいなのかと思っているのですが・・・

現在ライブラリやDLLについて学習中なので詳しい事が
よくわかっていないのでどなたか教えていただけませんでしょうか?
また上記の『ラップ』と言う言葉の定義はあってますか?
宜しくお願いします。

つばさ 2007/07/10(火) 10:18:53
こんちわ

ラップしてる元のライブラリの中身で
同一のものを更新やロックなど行っていると固まる気がします・・

まずはそのライブラリを見直してみてはいかがでしょう?

そのライブラリに問題がなければ
各スレッドで別のインスタンスを生成してるなら
競合はしないはずです

ラップは・・まぁ元になるライブラリを覆い隠すもの みたいな感じですかねぇ

元のライブラリの関数を見せたくない場合などによく使いますね

YouS 2007/07/10(火) 10:34:54
[[解決]]
つばささん有難う御座います。

>まずはそのライブラリを見直してみてはいかがでしょう?

フリーのライブラリなのですが、ソースは公開されていない為
中でどのように動作しているのかはわからないのです。

>そのライブラリに問題がなければ
>各スレッドで別のインスタンスを生成してるなら
>競合はしないはずです

そうですか。今思いつきましたがそれぞれのスレッドで
ライブラリの関数のポインタを調べて、アドレスが異なれば
インスタンスが同一か否かを調べる事は可能だったんですかね?
質問前に試してみれば良かったですね。すみません。

>元のライブラリの関数を見せたくない場合などによく使いますね
私の認識は間違っていなかったようで何よりです。

有難う御座いましたm(__)m

yoh2 [E-Mail] 2007/07/11(水) 02:55:32
> ライブラリの関数のポインタを調べて、アドレスが異なれば
> インスタンスが同一か否かを調べる事は可能だったんですかね?

スレッド毎にライブラリ関数のアドレスを取得して、それぞれ較べるということですか?
スレッドが異なっても、よほど変なことをしない限り同じ関数のアドレスは一緒ですよ。
関数がスレッドセーフかどうかは、関数のアドレスやプロトタイプなどの外見から判断することは不可能
で、純粋にその関数の実装に左右されます。
ライブラリソースが公開されていなければ、ライブラリの仕様書が頼りです。仕様にスレッドセーフである 
or スレッドセーフでない、とあれば完璧。
そうでない場合も、仕様からある程度推測することはできますが、予想を裏切る実装になっていることもし
ばしばありますので、スレッドセーフかどうか何も書かれていなければ、安全側に振って、スレッドセーフ
でないと思っておいた方が無難です。

wclrp ( 'o') [HomePage] 2007/07/11(水) 10:02:11
> 仮にGUIから各スレッドの呼び出しの際にクラスの
> ポインタを渡した場合は当然インスタンスは1つですから
> スレッドA、Bで同時にライブラリの関数が呼ばれた場合、
> 予測出来ない不具合が発生するのは理解できます。

class X { public: int value; void func() { ライブラリコール } };
X a,b;
と下場合
スレッドAでa.valueの操作とスレッドBでb.valueの操作を並列に行っても
問題は起きないでしょうけど
スレッドAでa.func()のコールとスレッドBでb.func()のコールを並列に行えば
スレッドセーフではないライブラリをスレッドA, Bで同時に呼んでしまうよ。

そもそも、あなたの発言にはロック(待ち処理)や排他制御を
ラップクラスに組み込んだとは書いてない。

俺の経験ではVisualStudioがフリーズすることがよくある。

> そのライブラリに問題がなければ
最初の発言でライブラリはスレッドセーフじゃないって書いてあるってば。

古いスレッドには追加発言できません。