問題タブ [c++builder-10.1-berlin]

For questions regarding programming in ECMAScript (JavaScript/JS) and its various dialects/implementations (excluding ActionScript). Note JavaScript is NOT the same as Java! Please include all relevant tags on your question; e.g., [node.js], [jquery], [json], [reactjs], [angular], [ember.js], [vue.js], [typescript], [svelte], etc.

0 投票する
2 に答える
500 参照

c++ - Embarcadero C++Builder でイベント ハンドラは再入可能ですか?

Embarcadero CB10.1 の再入可能性に関する問題の処理方法について、アドバイスをお願いしたいと思います。「すべての最適化を無効にする」を true に設定して、デバッグ構成でコンパイルします。私はWin7で実行しています。

簡単なテストケースがあります。2 つのボタンがあるフォーム。各ボタンの OnClick イベント ハンドラーは、CPU を集中的に使用する同じ関数を呼び出します。以下は、ヘッダー ファイルとそれに続くプログラム ファイルです。

- 1 番目のケース: 表示されているコードですが、ProcessMessages() への呼び出しはありません。

これを実行してボタン 1 をクリックすると、CPU 使用率が約 9 秒間ほぼ 100% に跳ね上がります。この間、フォームは応答しなくなります。フォームを移動したり、ボタン 2 をクリックしたりできません。

それは私が期待するように機能します。

2 番目のケース : CPU を集中的に使用する機能中にフォームをユーザーに応答させるために、示されているように ProcessMessages() 呼び出しを追加しました。これで、フォームを移動して他のボタンをクリックできるようになりました。

ボタン 1 をもう一度クリックしたり、ボタン 2 をクリックしたりすることもできるため、これは必ずしも良いことではありません。CPU を集中的に使用する関数が 2 回目に実行されるのを防ぐために、静的なブール値フラグ "InUse" を作成しました。関数の開始時に設定し、関数の完了時にクリアします。

そのため、CPU を集中的に使用する関数に入ったときにフラグを確認し、フラグが設定されている場合 (ボタンを前回クリックして設定されている必要があります)、メッセージを表示してフラグがクリアされるのを待ちます。

しかし、フラグはクリアされず、私のプログラムは「while」ステートメントで永遠にループします。CPU を集中的に使用する関数が完了するのを待ってから、もう一度実行するようにプログラムを設定したいと思います。

デッドロックに達した後に Spin() 関数にブレークポイントを設定すると、どちらのイベントも実行されていないことが示され、決して起動されません。

VCL がスレッド セーフではないことはわかっていますが、ここではすべての処理がメイン スレッドで行われます。私の実際のコードでは、VCL 関数の呼び出しが多いため、CPU を集中的に使用する関数はメイン スレッドに残す必要があります。

クリティカル セクションとミューテックスを検討しましたが、すべてがメイン スレッドにあるため、それらを使用してもブロックされません。

多分それはスタックの問題ですか?デッドロックなしでこれを処理できるソリューションはありますか?