Process ID's (PIDS). Every process on the system has a PID. You imagine that the OS itself has a PID of 0. No created process has a PID of 0. Every process (except PID 0, the OS) has exactly one parent process. It can also have any number of child processes. These processes form a tree, with the OS (PID 0) as the root. Now, the fork () method in the parent returns the PID of the child process. The fork() method in the child returns 0. That does not mean that the child's PID is 0. It just means that the fork method returns 0, and in that way, the child knows that it's the child. If the child needs to know it's own PID, or its parent's PID, there are other commands to acquire this information, but the fork() method itself does not provide that information. Child is writing Y. Parent is writing J. Parent and child are running simultaneously. Child runs seekp (0) (move to beginning of file.) Parent runs seekp (0) (move to beginning of file.) Child runs out << "Y" (this writes a Y to the beginning of the file and advances the file pointer, so the file pointer is now at position 1.) Parent runs out << "J" (this writes a J to the file, but since the file pointer is at position 1, the "J" gets written at position 1. One of the issues of parallel programming is that you don't actually know exactly the order in which certain commands are firing. This is called a "race condition." you have a file variable (hello) which is an object containing among things a pointer to an internal file variable maintained by the operating system that keeps track of the file pointer. When you fork() you now two copies of hello, one in the parent and one in the child, but since the child's is an exact copy of the parent, they both point to the same internal file variable. Parent: hello --> internal hello structure --> file and it's pointer, (where you are in the file) Child: hello ----^ With a slight modification: If you open the file AFTER you fork, then a copy isn't made the fork, since the original did not exist at the time of the fork. Fork first: Parent: hello --> internal hello structure --> file Child: hello --> different internal hello structure --> file Processes vs. threads. Processes time share with other processes on a machine. Each process has its own memory. If you set a variable in one process, other process don't know about it. If you want to coordinate processes--and sometimes you do--you have to send explicit messages between the processes. But threads all lie in the same process. At any given time only one thread is running within that process. (So, just as the OS time shares between all the processes, each process time shares among all its threads). Because all threads are part of the same process, they share essentially everything. If one thread changes a variable, that variable is changed for all the threads. A command is "atomic" if the command cannot be interrupted by switching to another thread. cout << "This" is an atomic statment. It will not partially print out the thing before switching. It will complete the command entirely or not do it all until it gets control again. However, cout << "this" << "that" is NOT an atomic statement. It might print "this" and then not get to printing "that" for a while.