- Windows Processes and Threads
- Process Creation
- Process Handle Counts
- Process Identities
- Duplicating Handles
- Exiting and Terminating a Process
- Waiting for a Process to Terminate
- Environment Blocks and Strings
- Example: Parallel Pattern Searching
- Processes in a Multiprocessor Environment
- Process Execution Times
- Example: Process Execution Times
- Generating Console Control Events
- Example: Simple Job Management
- Job Objects
- Summary
- Exercises
Exiting and Terminating a Process
After a process is complete, the process, or more accurately, a thread running in the process, can call ExitProcess with an exit code.
VOID ExitProcess (UINT uExitCode)
This function does not return. Rather, the calling process and all its threads terminate. Termination handlers are ignored, but there will be detach calls to DllMain (see Chapter 5). The exit code is associated with the process. A return from the main program, with a return value, will have the same effect as calling ExitProcess with the return value as the exit code.
Another process can use GetExitCodeProcess to determine the exit code.
BOOL GetExitCodeProcess ( HANDLE hProcess, LPDWORD lpExitCode)
The process identified by hProcess must have PROCESS_QUERY_INFORMATION access (see OpenProcess, discussed earlier). lpExitCode points to the DWORD that receives the value. One possible value is STILL_ACTIVE, meaning that the process has not terminated.
Finally, one process can terminate another process if the handle has PROCESS_TERMINATE access. The terminating function also specifies the exit code.
BOOL TerminateProcess ( HANDLE hProcess, UINT uExitCode)
Caution: Before exiting from a process, be certain to free all resources that might be shared with other processes. In particular, the synchronization resources of Chapter 8 (mutexes, semaphores, and events) must be handled carefully. SEH (Chapter 4) can be helpful in this regard, and the ExitProcess call can be in the handler. However, __finally and __except handlers are not executed when ExitProcess is called, so it is not a good idea to exit from inside a program. TerminateProcess is especially risky because the terminated process will not have an opportunity to execute its SEH or DLL DllMain functions. Console control handlers (Chapter 4 and later in this chapter) are a limited alternative, allowing one process to send a signal to another process, which can then shut itself down cleanly.
Program 6-3 shows a technique whereby processes cooperate. One process sends a shutdown request to a second process, which proceeds to perform an orderly shutdown.
UNIX processes have a process ID, or pid, comparable to the Windows process ID. getpid is similar to GetCurrentProcessId, but there are no Windows equivalents to getppid and getgpid because Windows has no process parents or groups.
Conversely, UNIX does not have process handles, so it has no functions comparable to GetCurrentProcess or OpenProcess.
UNIX allows open file descriptors to be used after an exec if the file descriptor does not have the close-on-exec flag set. This applies only to file descriptors, which are then comparable to inheritable file handles.
UNIX exit, actually in the C library, is similar to ExitProcess; to terminate another process, signal it with SIGKILL.