NetServerEnum block quando il thread è terminato externaly

(Lavorando con Win32 API, in ambiente C con VS2010)

Ho una app a due thread. Il primo thread si arresta il secondo e attende un determinato intervallo – “TIMEOUT”, quindi chiama TerminateThread() su di esso. Nel frattempo, il secondo thread chiama NetServerEnum() .

Sembra che quando viene raggiunto il timeout, se NetServerEnum restituito correttamente o meno, il primo thread viene sbloccato. Ho già notato che NetServerEnum crea thread di lavoro di sua proprietà.

ntdll.dll!RtlInitializeExceptionChain con uno di quei thread in deadlock, in genere su ntdll.dll!RtlInitializeExceptionChain , incapace di uscire con grazia dal mio processo.

Come troppo a lungo per un commento:

Verbatim da MSDN , permettimi di usare il modulo di risposta (sottolineatura da parte mia):

TerminateThread è una funzione pericolosa che dovrebbe essere utilizzata solo nei casi più estremi. È necessario chiamare TerminateThread solo se si conosce esattamente cosa sta facendo il thread di destinazione e si controlla tutto il codice che il thread di destinazione potrebbe essere in esecuzione al momento della chiusura. Ad esempio, TerminateThread può causare i seguenti problemi:

  • Se il thread di destinazione possiede una sezione critica, la sezione critica non verrà rilasciata.
  • Se il thread di destinazione sta allocando memoria dall’heap, il blocco heap non verrà rilasciato. * Se il thread di destinazione sta eseguendo alcune chiamate kernel32 quando viene terminato, lo stato kernel32 per il processo del thread potrebbe essere incoerente.
  • Se il thread di destinazione sta manipolando lo stato globale di una DLL condivisa, lo stato della DLL potrebbe essere distrutto, interessando altri utenti della DLL.

Dalla lettura di questo è facile capire perché è una ctriggers idea cancellare (terminare) un thread stucking in una chiamata di sistema.


Un ansible approccio alternativo alla progettazione dell’OP potrebbe essere quello di generare un thread che chiama NetServerEnum() e lasciarlo semplicemente funzionare finché la chiamata di sistema non viene restituita.

Nel frattempo, mentre il thread principale potrebbe fare altre cose, come ad esempio informare l’utente che la scansione della rete richiede più tempo come previsto.