2

継承された C# winforms コードで、ハンドルのリークの問題 (「このコマンドを処理するのに十分な割り当てがありません。」) があったため、Sysinternals のハンドルツールを使用して追跡しました。リークしていたのはイベント ハンドルであることが判明したので、Google で検索してみました ( 「もしかして: イベントハンドラー?」を返さないクエリを数回検索しました)。Junfeng Zhang 氏によると、イベント ハンドルは Monitor を使用して生成され、イベント ハンドルの破棄と同期プリミティブに関する奇妙なルールが存在する可能性があります。

このコードはHIDインターフェイスと多くのwin32マーシャリングと相互運用も扱っており、何もしていないため、ハンドルのリークの原因が完全に多くの同期を呼び出す長寿命のオブジェクトに完全に起因するかどうかは完全にはわかりません。気づいた同期。いずれにせよ、これを windbg で実行して、ハンドルの発生元を追跡し始め、コードのこのセクションの学習にも多くの時間を費やしますが、どのイベントに関する情報を見つけるのに非常に苦労しましたハンドルは最初の場所にあります。

イベント カーネル オブジェクトのmsdn ページは、一般的な同期の概要にリンクしているだけです...では、イベント ハンドルとは何ですか?また、それらはミューテックス/セマフォ/その他とどう違うのでしょうか?

4

2 に答える 2

3

NT カーネルは、イベント オブジェクトを使用して、シグナルを待機しているエンティティにシグナルを転送できるようにします。ミューテックスとセマフォも待機可能なカーネル オブジェクト (カーネル ディスパッチャ オブジェクト) ですが、セマンティクスが異なります。私がそれらに遭遇したのは、ドライバーで IO が完了するのを待っているときだけでした。

あなたの問題に関する私の理論は、おそらく欠陥のあるドライバーですか、それとも特殊なハードウェアに依存していますか?

編集: 詳細情報( Windows Internals 5th Edition - Chapter 3 System Mechanics から)

一部のカーネル ディスパッチャ オブジェクト (mutex、セマフォなど) には、所有権という概念があります。そのため、解放された 1 つの待機中のスレッドが解放されるというシグナルが送信されると、これらのリソースが取得されます。そして、他の人は待ち続ける必要があります。イベントは所有されていないため、任意のスレッドでリセットできます。

また、次の 3 種類のイベントがあります。

  • 通知 : 待機中のすべてのスレッドが解放されるシグナル
  • 同期 : シグナルが発生すると、1 つの待機中のスレッドが解放されますが、イベントはリセットされます
  • Keyed : シグナル送信者と同じプロセス内の 1 つの待機中のスレッドがシグナル状態になると、解放されます。

私が学んだもう 1 つの興味深いことは、クリティカル セクション( c# のロック プリミティブ) は実際にはカーネル オブジェクトではなく、キー付きイベント、または必要に応じてミューテックスまたはセマフォから実装されるということです。

于 2010-03-03T22:46:25.743 に答える
2

カーネルイベント オブジェクトについて話している場合、イベント ハンドルはシステムがこのオブジェクトを保持するハンドル (Int) になり、他のオブジェクトがそれを参照できるようになります。IE 「ハンドル」を保持します。

お役に立てれば!

于 2010-03-03T22:43:11.583 に答える