2012-02-17 7 views
6

多量のマルチスレッドのアプリケーションで多数のクラッシュが発生しています。これらMSDN pagetechnical notethis article on TLS読書CWnd :: GetSafeHwnd()とCWnd :: m_hWnd ThreadSafeはありますか?

は、IはCWndのオブジェクトがスレッドdependendentメモリアクセスであるTLSにHWNDにマッピングされることを理解しています。

私はCWndスレッドのリモートアクセスのように見えるものすべてを切り離し、HWND参照に変換してから、通信ポートとしてPostMessageを使用します。 (そして、今のところ現行のコードで見る限り、膨大な量の作業を表しています。私は解決策を完成させていましたが、時間がかかるので、議論しなければなりませんでした)。

私の同僚の一人は、外国人のスレッドにCWnd *を保持し、PostMessageポリシーをそのまま使用することを強く主張しましたが、外部スレッドのCWnd :: GetSafeHwnd()またはpMyCWnd-> m_hWndを使用します。ネイティブのHWNDを復旧します。

私はGetSafeHwndは()、 スレッドセーフであるとのCWndがオブジェTLSにいること、それは別のスレッドの値が異なっているということ見てきたどこと主張してきました。 私は間違っていますか? MSDNでは、「予期しない結果」という用語を使用しています。

作成者のスレッドから外部スレッドでCWnd :: GetSafehwnd()またはpMyCWnd-> m_hWndを呼び出すことはできません。

これは安全であるかどうかを示すMSDNのドキュメントをお持ちですか?

答えて

7

CWndsはHWNDにマップされません。 HWNDはCWndにマップされ、これはスレッドごとに発生します。 CWndオブジェクトはTLSにはありません(どのように動作しますか)が、一時的なCWndオブジェクトはスレッドごとに作成されます。

一時的ににアクセスする間違ったスレッドからCWndオブジェクトは間違いなく(マークランソムによって説明された理由のため)悪い考えです。

しかし、永続的なCWndオブジェクト(アプリケーションのメインウィンドウを表す)があれば、それが作成されると、どのスレッドからでもm_hWndメンバにアクセスする際に問題はありません。それは決して変化しないメモリ内の単なる価値です。

この問題が発生した場合(明示的に文書化されていないため)、HWNDのコピーを作成してスレッドにアクセスさせます。

P.S. Here's the article you linked to英語です。

1

複数のスレッドがすべて同時にHWNDにアクセスしようとしているマルチスレッドアプリケーションを使用している場合は、設計上問題があるように聞こえます。あなたのスレッドを計算に制限することはできませんし、メインスレッドでUIの問題を処理することはできませんか?これは良いマルチスレッドアプリケーションの典型的な設計です。

+0

いい加減なアドバイスがありますが、多くのLOCをコード化することができず、10年以上経っていますが、私はそれを拭くことができない巨大な歴史があります:-) –

+0

あなたの質問は基本的に "私はこの非常に危険なことをしなければならない、それは安全ですか?そして答えはおそらく "何もそれを安全にするものではない"ということでしょう。あなたはそれをもっと安全にすることはできますが、現在の設計ではクラッシュフリーにすることはできません。 – StilesCrisis

+0

(私は関係することができます。私は10歳のMFCコードベースで作業しています。スレッドはありません。元のコーダーはそれほどスマートではありませんでした) – StilesCrisis

4

GetSafeHwndは、thisがNULLかどうかを確認するラッパーで、そうでない場合はm_hWndを返します。これ以上のスレッドセーフではありませんm_hWnd自体です。

一時的なCWnd *を作成すると、MFCはメッセージループの次のパスなど、安全であると考えられるポイントで破棄します。 MFCを使用する複数のスレッドがある場合、一時オブジェクトはまだ使用中に破棄される可能性があります。あなたのスレッドから何もできないことは、このエラーを検出します。

+0

はすべてCWnd * temporariesかどうかですか?私はウィンドウをinstanciatingするときにクリエイターのスレッドで作成されたCWnd *を意味します、それは一時的ですか? (私はCWnd :: FromHandle()によって計算されたものではない) –

関連する問題