Condividi tramite


Terminazione di un processo

La terminazione di un processo presenta i risultati seguenti:

  • Tutti i thread rimanenti nel processo vengono contrassegnati per la terminazione.
  • Tutte le risorse allocate dal processo vengono liberate.
  • Tutti gli oggetti kernel sono chiusi.
  • Il codice del processo viene rimosso dalla memoria.
  • Il codice di uscita del processo è impostato.
  • L'oggetto process viene segnalato.

Mentre gli handle aperti agli oggetti kernel vengono chiusi automaticamente quando termina un processo, gli oggetti stessi esistono fino a quando non vengono chiusi tutti gli handle aperti. Pertanto, un oggetto rimarrà valido dopo un processo che lo usa termina se un altro processo ha un handle aperto.

La funzione GetExitCodeProcess restituisce lo stato di terminazione di un processo. Durante l'esecuzione di un processo, lo stato di terminazione è STILL_ACTIVE. Quando un processo termina, lo stato di terminazione cambia da STILL_ACTIVE al codice di uscita del processo.

Quando un processo termina, lo stato dell'oggetto processo viene segnalato, rilasciando eventuali thread che erano in attesa del processo di terminazione. Per altre informazioni sulla sincronizzazione, vedere Sincronizzazione dell'esecuzione di più thread.

Quando il sistema termina un processo, non termina i processi figlio creati dal processo. La terminazione di un processo non genera notifiche per WH_CBT procedure di hook.

Usare la funzione SetProcessShutdownParameters per specificare determinati aspetti della terminazione del processo all'arresto del sistema, ad esempio quando un processo deve terminare rispetto agli altri processi del sistema.

Modalità di chiusura dei processi

Un processo viene eseguito fino a quando non si verifica uno degli eventi seguenti:

  • Qualsiasi thread del processo chiama la funzione ExitProcess . Si noti che alcune implementazioni della libreria C run-time (CRT) chiama ExitProcess se il thread primario del processo restituisce.
  • L'ultimo thread del processo termina.
  • Qualsiasi thread chiama la funzione TerminateProcess con un handle per il processo.
  • Per i processi della console, il gestore del controllo console predefinito chiama ExitProcess quando la console riceve un segnale CTRL+C o CTRL+BREAK.
  • L'utente arresta il sistema o lo disconnette.

Non terminare un processo a meno che i thread non si trovino in stati noti. Se un thread è in attesa di un oggetto kernel, non verrà terminato fino al completamento dell'attesa. Ciò può causare l'arresto della risposta dell'applicazione.

Il thread primario può evitare di terminare altri thread indirizzandoli a chiamare ExitThread prima di causare la terminazione del processo (per altre informazioni, vedere Terminazione di un thread). Il thread primario può comunque chiamare ExitProcess in seguito per assicurarsi che tutti i thread vengano terminati.

Il codice di uscita per un processo è il valore specificato nella chiamata a ExitProcess o TerminateProcess o il valore restituito dalla funzione main o WinMain del processo. Se un processo viene terminato a causa di un'eccezione irreversibile, il codice di uscita è il valore dell'eccezione che ha causato la terminazione. Questo valore viene inoltre usato come codice di uscita per tutti i thread in esecuzione quando si è verificata l'eccezione.

Se un processo viene terminato da ExitProcess, il sistema chiama la funzione di ingresso di ogni DLL associata con un valore che indica che il processo si scollega dalla DLL. Le DLL non vengono notificate quando un processo viene terminato da TerminateProcess. Per altre informazioni sulle DLL, vedere Librerie di collegamento dinamico.

Se un processo viene terminato da TerminateProcess, tutti i thread del processo vengono terminati immediatamente senza possibilità di eseguire codice aggiuntivo. Ciò significa che il thread non esegue codice nei blocchi del gestore di terminazione. Inoltre, non vengono notificate dll associate che il processo viene scollegato. Se è necessario terminare un processo con un altro processo, la procedura seguente offre una soluzione migliore:

  • Per creare un messaggio privato, entrambi i processi chiamano la funzione RegisterWindowMessage .

  • Un processo può terminare l'altro processo trasmettendo un messaggio privato usando la funzione BroadcastSystemMessage come indicato di seguito:

     DWORD dwRecipients = BSM_APPLICATIONS;
        UINT uMessage = PM_MYMSG;
        WPARAM wParam = 0;
        LPARAM lParam = 0;
    
        BroadcastSystemMessage( 
            BSF_IGNORECURRENTTASK, // do not send message to this process
            &dwRecipients,         // broadcast only to applications
            uMessage,              // registered private message
            wParam,                // message-specific value
            lParam );              // message-specific value
    
  • Il processo che riceve il messaggio privato chiama ExitProcess per terminare l'esecuzione.

L'esecuzione delle funzioni ExitProcess, ExitThread, CreateThread, CreateRemoteThread e CreateProcess viene serializzata all'interno di uno spazio indirizzi. Si applicano le restrizioni seguenti:

  • Durante l'avvio del processo e le routine di inizializzazione DLL, è possibile creare nuovi thread, ma non iniziano l'esecuzione fino al termine dell'inizializzazione DLL per il processo.
  • Solo un thread alla volta può trovarsi in una routine di inizializzazione o scollegamento dll.
  • La funzione ExitProcess non restituisce fino a quando non sono presenti thread nella routine di inizializzazione o scollegamento della DLL.