[過去ログ] マルチスレッドプログラミング相談室 その4 (1001レス)
前次1-
抽出解除 レス栞

このスレッドは過去ログ倉庫に格納されています。
次スレ検索 歴削→次スレ 栞削→次スレ 過去ログメニュー
リロード規制です。10分ほどで解除するので、他のブラウザへ避難してください。
235
(6): 225 2006/01/28(土)14:57 AAS
>>234 の続き
1.A.EXE: BCB5 で作成、B.DLL: VC6 libcmt.lib で作成
2.A.EXE: BCB5 で作成、B.DLL: VC6 msvcrt.lib で作成
3.A.EXE: BCB5 で作成、B.DLL: BCB5 で作成

結果:
1:DllMain で DisableThreadLibraryCalls を呼ぶとメモリリークする
  (test を呼ぶ度にメモリ使用量が増える)
  DllMain で DisableThreadLibraryCalls を呼ばなければメモリリークしない
  (test を何回呼んでもメモリ使用量は変わらない)
2:DllMain で DisableThreadLibraryCalls を呼んでも呼ばなくてもメモリリークしない
省8
236
(1): 225 2006/01/28(土)14:59 AAS
>>235 の続き
結論:
BCB5/VC6 で作成した B.DLL においては、C ランタイムルーチンのうち、少なくとも
malloc/free/new/delete しか使わない分には、A.EXE で作成したスレッド内で B.DLL
の関数を呼び出してもメモリリークしない。スレッドの作成に _beginthread(ex) を
使う必要もない。

VC6 で MSVCRT.DLL とリンクする B.DLL では、A.EXE で作成したスレッド内で B.DLL
の関数(内部で C ランタイム関数を呼ぶもの)を呼び出してもメモリリークしない。

VC6 で libcmt.lib とスタティックリンクする B.DLL では、DllMain で
DisableThreadLibraryCalls() を呼ばなければ、A.EXE で作成したスレッド内で
省12
238
(1): 225 2006/01/28(土)18:02 AAS
> 複数のスレッドで同時に1つのワークエリアを参照していれば、
> 各スレッドがお互いに1つのワークエリアをぶっ壊しあう。

マルチスレッド対応のランタイムでは、そのような問題は起こらないことが
保証されているものだと思ってました。
_beginthread(ex) の説明を読む限り、メモリリーク問題以外については
何も記述されていません。

> つか、なんでCreateThread()で試してるんだ?

確認したかったのは、「A.EXE で作成したスレッド内で B.DLL 内の関数を
呼ぶことが出来るかどうか」だからです。

A.EXE は BCB5 で作成していて、B.DLL は VC6 で作成しています。
省9
239
(2): 2006/01/28(土)18:45 AAS
>>238
> マルチスレッド対応のランタイムでは、そのような問題は起こらないことが
> 保証されているものだと思ってました。

思うのは勝手だけど、正しい使い方をしないと正しい挙動はしてくれないよ。
この場合、_beginthread*()を呼ばないと、「正しい挙動」はしてくれない。
なぜなら、Cランタイムをスレッドセーフにする肝心の処理を_beginthread*()がやるから。

ついでに言えば、問題はB.DLLだけの話ではなくて、A.EXEのランタイムに
何を使ってるか? というのも重要。にも関わらず、>>235でその点に
一切触れていない点からも、喪前さんの理解が足りないことが伺える。
240: 225 2006/01/28(土)20:18 AAS
>>239
> なぜなら、Cランタイムをスレッドセーフにする肝心の処理を_beginthread*()がやるから。

_beginthread(ex) と _endthead がやるのは、スレッドごとに必要なメモリ
の割り当てと解放を行うことですよね?

_beginthread を使わなかったせいで、ランタイムルーチンを呼び出し時に
そのスレッドではまだメモリが割り当てられてなかったなら、その場で動的に
割り当てれば問題ないでしょう。実際、動的に割り当ててると思うんだけど。

問題なのは、スレッドの終了を知ることが出来なくなるせいで、割り当てた
メモリを解放する機会が得られなくなり、その結果としてメモリリークが発
生する、ということではないの?
省12
244
(1): 225 2006/01/28(土)21:40 AAS
>>243
やっぱりそうですか。(^^;

>>235 の結果から、(この検証が正しければ)メモリリークに関しては
処理系依存ということになったわけだし、ドキュメント化されてるわけ
でもないようだから、結局のところ結論なんて出ないんだろうな…。

「A.EXE で作成したスレッドから B.DLL の関数を呼び出すとメモリリークする」
のだとすると、Susie プラグインとか、自分ではメンテナンス出来ないプラグイン
方式の DLL を使うアプリをマルチスレッド化するのは非現実的ということになっ
てしまうのか…。ほとんどの DLL は C ランタイムを使用してるだろうから。

一度作成したスレッドはアプリが終了するまで使い回すようにするしかないの
省1
249: 225 2006/01/29(日)04:20 AAS
>>248
> 「EXE・DLLの両方で同じライブラリ使ってれば、相互に呼び合いしても問題ない」

DLL は他人が作ってるので自分でいじれないし、EXE は GUI の
関係上 BCB しか使えないので。

> 「泥沼に足突っ込みたくなければ推奨されてるやり方を使え」

EXE で作成したスレッドから DLL の関数を呼ぶ場合の推奨されてる
やり方とは?EXE/DLL ともに MSVCRT を使うことですか?

> AdvancedWindowsなりMSDNなりCRTのソースなり自分で読んで勉強してくれ
省6
前次1-
スレ情報 赤レス抽出 画像レス抽出 歴の未読スレ AAサムネイル

ぬこの手 ぬこTOP 0.034s