0

私のプログラムの構造では、「どこから呼び出されるか」と「何が行われるか」を別々のソースファイルに分割しました。実用性の問題として、これにより、プログラムをスタンドアロンとしてコンパイルしたり、DLLに含めたりすることができます。以下のコードは実際のコードではなく、同じ点を示す単純化された例です。

ここには3つの相互作用するコンポーネントがあります。DLL、DLLとそのソースファイルをロードするカーネルモードプログラム、および個別に維持されるソースを含むユーティリティプログラムです。

DLL形式では、プログラムはスレッドとしてロードされます。カーネルモードアプリケーションベンダーのドキュメントによると、カーネルプログラムの初期化後にWin32 API関数を呼び出す機能が失われるため、スレッドをアクティブスレッドとしてロードします(ウェイクアップできないため、CREATE_SUSPENDEDを使用するのではありません)。

フラグ変数を監視して、エレガントではないが機能的なものを介して有用なことをいつ実行するかを認識できるようにします。

while ( pauseThreadFlag ) Sleep(1000);

最大1秒の遅延は許容範囲内であり(プロセス全体が長く、頻繁に呼び出されることはありません)、システムに影響を与えることはないようです。

スレッドソースファイルで、変数を次のように宣言します

volatile bool pauseThreadFlag = true;

私が宣言したDLLソースファイル内

extern volatile bool pauseThreadFlag;

スレッドを実行する準備ができたら、DLLで設定します

pauseThreadFlag = false;

std :: stringオブジェクトを揮発性として宣言するのに苦労したので、代わりに、スレッドのソースファイル内でパラメーターをグローバル変数として宣言し、スレッドのソースに常駐するDLL呼び出しセッターを使用しました。スレッドを自由にインスタンス化できれば、これらの文字列はパラメータになります。

(これらすべてに欠けているのは、スレッドセーフのために変数をロックすることです。これは私の次の「やるべきこと」です)

これは悪いデザインだと思います...機能的ですが複雑です。私が言及した制約を考えると、これを回避するためのより良い方法はありますか?

スレッドの作成時に文字列が空になる場合でも、スレッドの作成時に指定されたLPVOID lpParams変数を使用して文字列オブジェクトへのポインターを保持し、スレッドから直接アクセスすることで、修正の可能性があると考えていました。スレッドプログラムの宣言、セッターなどを完全に消去しますか?これが機能する場合は、一時停止フラグもそこで参照でき、extern宣言が削除されます(ただし、オプティマイザーを示唆するために、揮発性として宣言する必要があると思います)。

違いが生じる場合、環境はVisual Studio 2010、C ++、ターゲットプラットフォームWin32(XP)です。

ありがとう!

4

2 に答える 2

1

すべてのコンポーネントがカーネルモードで実行されている場合は、 KeInitializeEventKeSetEventKeResetEvent 、およびKeWaitForSingleObjectを確認する必要があります。これらはすべて、同等のユーザーモードと同じように機能します。

于 2011-07-20T21:31:49.743 に答える
0

構造体を削除して、すべてのデータをカプセル化するオブジェクトに置き換えることになりました。ゲッターとセッターでいっぱいで、少し恐ろしいですが、この特定のケースでは、アクセスメソッドを使用して、ロックが適切に設定/設定解除されていることを確認しています。

このオブジェクトへのvoidキャストポインタを使用すると、オブジェクトが正しく渡され、非常に安定しているように見えます。

于 2011-07-26T14:19:06.453 に答える