0

以前に尋ねられたSO の質問を解決しようとしているときに、スレッドがなくても問題が発生することがわかりました。

私が今持っているのは、- を呼び出す非常に単純なシングル スレッド コードですNetServerEnum()NetApiBufferFree()返されると、プロセスを終了するはずの main から呼び出されて返されます。その時点で、私のスレッドは本当に終了しますが、プロセスは終了しません.4つのスレッドが開かれているためです(私ではありません):

1 * ntdll.dll!TplsTimerSet+0x7c0(スタックはntdll.dll!WaitForMultipleObjects)

(これは への呼び出しで開かれましたNetServerEnum())

3 * ndll.dll!RtValidateHeap+0x170(スタックはntdll.dll!ZwWaitWorkViaWorkerFactory+0xa)

(これらは私のコードが戻ったときに開いています)

更新: ntdll.dll!TplsTimerSet+0x7c0 を外部で (プロセス エクスプローラーを使用して) 実行しているスレッドを強制終了すると、が返される前にmain()、プログラムは正常に終了します。知っておくと便利だなと思いました。

UPDATE2: (いくつかの技術情報) 私が使用している: Win7 Enterprise SP1上のMS Visual Studio 2010 Ultimate x64 (SP1Rel) コードは C (ただし、c++ スイッチがオンになっているのでコンパイル) サブシステム: WINDOWS コンパイラ: cl.exe (IDE を使用)他のすべてのパラメータはデフォルトです。

私は自己変更されたエントリポイント ( /ENTRY:"entry") を使用していますが、それは私のプログラムで唯一の機能です):

int entry(void)
{
SERVER_INFO_101* si;
DWORD a,b;
NET_API_STATUS c;
c = NetServerEnum ( NULL , 101 , (LPBYTE*) &si , MAX_PREFERRED_LENGTH , &b ,  &a  , SV_TYPE_WORKSTATION, NULL , 0 );

c = NetApiBufferFree (si);

Sleep(1000);

return 0;

}

前述のすべてのテストは、約 100 ユニットの Windows ドメイン ネットワーク内で実行されました。

更新 3: (非仮想) WinXP 32bitでテストした場合、この問題は発生しません。(同じバイナリですが、Win7 x64 では 2 つのバイナリがテストされました - 32bit over WOW とネイティブ x64)

4

1 に答える 1

0

カスタム エントリ ポイントを使用すると、ランタイム ライブラリがバイパスされます。つまり、プロセスを終了する必要があります。実行中のスレッドがなくなると、プロセスは暗黙的に終了しますが、ご存知のように、オペレーティング システムはユーザーに代わって、ユーザーが制御できないスレッドを作成する場合があります。

あなたの場合、関数ExitProcessの最後で明示的に呼び出すだけです。entry()

int entry(void)
{
   SERVER_INFO_101* si;
   DWORD a,b;
   NET_API_STATUS c;

   c = NetServerEnum ( NULL , 101 , (LPBYTE*) &si , MAX_PREFERRED_LENGTH , &b ,  &a  , SV_TYPE_WORKSTATION, NULL , 0 );

   c = NetApiBufferFree (si);

   Sleep(1000);

   ExitProcess(0);
}

への呼び出しがなくExitProcess、カスタム エントリ ポイントがある場合、表示される動作は期待どおりです。

于 2013-07-04T23:14:34.950 に答える