An application that has been loaded into memory and prepared for execution is called a process. Each process has at least one thread, called the primary thread. A process consists of the code, data, and other resources, such as files and pipes, that belong to the application. A thread consists of a set of instructions, related CPU register values, and a stack. When Win32 executes an application, it confirms that the process's code and data are in memory and that the thread's registers and stack are set before it starts the application. Each application has access to all the computer's resources, such as memory, disk drives, screen, keyboard, and the CPU itself. The system carefully manages these resources so that applications can access them without conflict.
A process can have more than one thread. Each thread runs independently, keeping its own stack and register values. The threads of a process share the globally defined variables of the process. It is possible for any thread to control the execution of another thread if it has a handle to that thread's object with the appropriate access permissions. This handle allows the controlling thread to suspend, resume, or terminate the other thread, as well as to adjust its priority, or wait for it to terminate. Synchronization can also be achieved if the threads to be coordinated have handles to the same synchronization objects.
A thread terminates when it returns or calls the ExitThread function; and a process terminates when the primary thread returns or when any of its threads calls the ExitProcess function. Any files or other resources left open when the process terminates are closed automatically. When a thread terminates, however, any open resources remain open until another thread closes them or the process ends.
DLLs that are used by a process are notified when a process starts and terminates, and also when any of its threads that use the DLL start or terminate. For each of these events, the LibMain function of the DLL is called with a code that indicates the reason. Refer to the chapter on Dynamic Link Libraries for more information.
Any thread of a process can create a child process by calling CreateProcess. The Win32 API also retains two other obsolete process creation functions, LoadModule and WinExec, that are implemented by calling CreateProcess . The child process has its own code, data, and a virtual address space that is distinct from that of the parent process. If there are multiple executing instances of the same executable module, each has its own data segment and address space, although they can share pages of code and initialized data that have been loaded into memory.
The parent process can pass command line arguments to its child process. The parent process can allow the child process to inherit its environment variables, or it can specify a new set of environment variables for the child. Similarly, the parent can specify the current directory of the child or allow it to inherit the parent's. The parent controls whether the child inherits any of its open handles, such as file handles; and it can allow it to inherit some resources while preventing the inheritance of others. The child process can use the inherited resources without preparing them. For example, if the parent process opens a file for reading and then starts a child process, the child process can read from the file immediately without opening the file. Once the child process is created, however, additional resources the parent process creates are not available to the child process. Similarly, resources the child process creates are not available to the parent process. Note that this differs from the availability of resources to the threads of the same process, since a resource opened by any thread is accessible to all existing threads of the process, as well as to any threads that are created in the future.
For console applications, the parent process can create a detached child process that executes in the background, or it can create a new console window for the child. For GUI applications or for console applications that create a new console window, the parent can specify the location, size, title, and appearance of the child's main window. The parent can create a child process in a suspended state, and control when its execution is resumed.
Synchronization between the parent and child process can be achieved in several ways. The parent process has a handle to the child process that it can use at any time to determine whether the child is still executing or to wait for the child to terminate . Different types of synchronization objects are also available to coordinate the execution of multiple processes. See Chapter 4, “Synchronization” for more information.
Interprocess communication can be accomplished through named or anonymous pipes (see the example in this chapter, and additional information in $ch_pipes)) and through shared memory (see Chapter 7, “File Mapping”).