A program executes in a particular environment that consists of environment variables, which have the same relationship to a program as global variables have to a function. The purpose of environment variables is to set up an appropriate environment for program execution, and they also represent a possible data input into a program. Most operating systems provide the programmer with system calls to create environment variables and to set or fetch their values.
Besides environment variables, C/C++ programs have other means of receiving small amounts of data upon startup in the form of commandline arguments. The operating system creates a dynamic structure that is akin to a dynamic two-dimensional array, and one of the command-line arguments (words) is stored as a string in each of the "rows" of the structure. The very first row carries the program pathname and the very last one is empty. A C/C++ program receives this structure via the char** (or equivalently the char*  ) argument of the function main() .
A process is a fundamental concept in UNIX, while in Windows it is a concept derived from the fundamental concept of thread. A simple definition of a process is "a program in execution", though in UNIX they mean slightly different things. The UNIX system call fork() is used to create a copy of a running process (of its process image) and install it as a new process. The original process is then called the parent process while the new process is called the child process. The respective process images are almost identical; the only difference is that in the parent process the return value of fork() is the process ID of the child process, whereas in the child process this value is 0. The return value of fork() is used to determine whether a given process is the parent or the child. Even though no new processes can be created directly in UNIX, this mechanism suffices for all practical purposes. In Windows, a new process can be created by a proper system call without being a copy of the parent process. The same effect is achieved in UNIX by using one of the exec () calls to switch to the execution of a different program within the same process. From our point of view, two attributes of a process - the uniqueness of the process image and the process ID - are of interest and are maintained throughout the life span of the process. Because the user spaces of the two processes are completely and physically separated, there is no reason to worry about simultaneous access of the two processes to data stored in the memory. However, this separation prevents the processes from communicating and exchanging data. For that purpose, special interprocess communication systems must be provided. These may be summarized as follows .
Messages - message queues are used in both UNIX and Windows; they use memory to store messages where the recipient processes can find them. The memory for messages is explicitly controlled by the messaging system.
Signals - a kind of 1-bit message that cannot queue; a notification that some event happened . No memory is involved.
Shared memory - a memory segment is made available to several processes, and it becomes an extension of their respective user spaces and can be accessed like "ordinary" memory. The shared memory segments can be very persistent (i.e., can outlive the process that created them) and can leak in a significant way. Under almost all circumstances, simple programming techniques can be used to prevent the leaks.
Pipes, or temporary pipes - usually are implemented as memory buffers accessible by two related processes; they allow one process to write into the pipe and the other process to read from the pipe. Besides the buffer residing in memory, no memory handling is involved. The pipes can be unidirectional or bidirectional.
FIFOs, or named pipes - like the temporary ones, but these can be used for unrelated processes and are accessed (like files) using a fixed name .
The term "thread" is derived from "thread of execution", which is represented by a sequence of instruction addresses as they are being executed. It is possible to run more than one thread within the same context (the same address space). The flow of control depends on the data being processed , and two threads are usually not identical because the latter may encounter different data. In UNIX, the so-called lightweight process consists of threads that are scheduled and controlled by the operating system, whereas user threads are scheduled and controlled by the process and so the operating system is not aware of them. On the other hand, threads in Windows are scheduled and controlled by the operating system. Like processes, threads are used to implement concurrent processing. Two of the advantages of threads are (i) the virtually nonexistent overhead for switching from one thread to another and (ii) the fact that only one process image (address space) needs to be maintained, whereas for processes two images must be maintained at the possibly significant cost of disk space and/or memory. The disadvantage of threads is that all kinds of resources are shared by the threads, compelling us to synchronize the threads and to provide protection for both the code (critical sections) and the data ( mutexes ). Careless multithreading can lead to memory leaks, but a proper programming approach can easily prevent this.