- - PR -
アンマネージドとマネージドのスレッド対応
投稿者 | 投稿内容 | ||||||||
---|---|---|---|---|---|---|---|---|---|
|
投稿日時: 2007-06-28 14:11
渋木さん、Atata!!さん、ありがとうございます。
分からないなりに自分でも色々と試してみたりしましたが、 やはりなちゃさんやAtata!!さんの言われることが原因のようです。 しかし相変わらず解決策を見出せていません。
地獄で足掻くしかないでしょうか・・・ しかもこれってマネージド、アンマネージドや.NETとかがメインの問題じゃないですよね。 自分の勘違いとは言え、ここにスレ立てちゃって申し訳ありませんでした。 | ||||||||
|
投稿日時: 2007-06-28 16:20
解決策はご自身で書き込まれている下記の方法で問題無いのではないでしょうか?
この問題が私の推論通りであればCOMの機能を使用して解決することも出来ますが、 経験上、新たな問題を発生させることの方が多いです。
私はVB.NETでマルチスレッドプログラミングの敷居が下がったため、 この類の問題は以前より増えているように感じます。(特にOCX関連) で、COM相互運用の問題として、ここに立てるのも悪くない気がします。 | ||||||||
|
投稿日時: 2007-06-28 18:41
RPCがメッセージまわしちゃってるということですか。 ややこしいですね。 | ||||||||
|
投稿日時: 2007-06-28 18:50
純粋な RPC はメッセージポンプは回さないです。 この場合はたぶん、LPC です。 サービスってことは別プロセスなんだから、そこで幾らポンプを回しても、呼び出し元には影響ないはずなんだけどなぁ。 | ||||||||
|
投稿日時: 2007-06-28 20:30
便宜上RPCと呼んでますが、この場合間違いなくLPCです。 サービス側のメソッドを呼び出して メソッドの呼び出し元に復帰する直前(スレッドコンテキストはSTAスレッド上)に、 RPCの実行キューから溜まった処理を取り出して実行していると思われます。 STAスレッドのメッセージポンプは動かないはずです。 この時キューから取り出した情報が、サービス側のメソッドを呼び出した結果であるならば、 そのまま呼び出し元に復帰すると考えられます。 | ||||||||
|
投稿日時: 2007-06-28 20:44
なんと言うか、実行キューとか再入とか書いたので誤解を与えている気がします。
更に言うと私が呼んでいるRPCの実行キューは、 呼び出し順番がよく分からないことが多いので、 キュー構造になっているかどうかも正直分かりません。 # まぁ、大体FIFOで動作してるように見えるんですが。 # このスレッドが面白いので、今日はあんまり仕事してないなぁ・・・。 | ||||||||
|
投稿日時: 2007-06-29 00:53
んーっと
どのスレッドがどのメソッドを呼んでどのキューを処理しているのか、 私にはよく理解できませんでした。 AP(MT) <-> OCX(ST) <-> DLL <-(LPC)-> ATL MultiThreadのAPからSingleThreadなOCX呼ぶところでキューが入るのはいいとして、 DLLからATL呼ぶときのLPCで OCXのメッセージポンプに戻らないと今回の様にはなりませんよね。 >実際には、RPCランタイムはSTAスレッドの実行キューに先に溜まっている処理を実行する。 >STAスレッドのメッセージポンプは動かないはずです。 実行キューを処理するのにメッセージポンプが動いてないとは どーゆーことでしょう? そういや「reentrant」という言葉なんですが、wikipediaによると >A computer program or routine is described as reentrant if it can be safely called recursively or from multiple processes. >リエントラント(Reentrant、再入可能)とは、プログラムやサブルーチンが、静的な内部状態をもたないので、再帰的にも、複数のスレッドからも、データを壊すおそれなく呼び出せる場合をいう。 とあり、すでに「可能」の意味があります。 英語で〜antは可能の意味を持ちますので。 ですので、「reentrantする」は変です。 「reentrantである」ならばそのままですが。 どうしても「再入する」といいたいときは「reentrance」ですね。 the reentrance to the RPC (RPCへの再入 the problem of reentrances (再入している問題 reentrant functions (再入可能な関数 あ、もうひとつ。 ># 実際のところマルチスレッドなので再入とは言えないか。 マルチスレッドでも再入です。 自分が抜けてない内に、他のスレッドか自分自身入れるのであれば再入可能。 自分が抜けてない内に、他のスレッドが入れるのであればスレッドセーフ。 | ||||||||
|
投稿日時: 2007-06-29 04:34
私が述べているSTAスレッドの実行キューとはWindowsのメッセージキューではありません。 (実際のところ実装がどうなっているかまでは分かりませんが) RPCランタイムが管理するデータの論理的な構造について述べているつもりです。 ですので、このキューはメッセージポンプとは関係がありません。 DLLからサービスのインターフェースプロキシを呼び出した際、 プロキシの内部で上記キューのデータが処理されます。 処理された結果、新しく別のメソッド呼び出しが開始されるわけです。 プロキシ内部で処理されるタイミングはLPC呼び出しの後であることは確かです。 あと、私の記述にも明らかな間違いがありました。 よくよく調べてみるとメソッドの復帰情報は実行キューには詰まれていないようです。 LPC(RPCも同様)呼び出しから復帰した時には既に復帰情報は得られています。 InsideDCOMのプロキシ/スタブの解説と今回の現象を再現するコードから確認しました。 失礼しました。
私の「re-entrant」の解釈はかなり間違ってますね。 今回のような話題を述べる時には特に気をつけたいと思います。 |