There are many different versions of UNIX; this FAQ, talks about features that are common to all of them.
Each process runs a single program and initially has a single "thread". So a process initially has one program counter, which keeps track of the next instruction to be executed. I'm not going to talk about it here but most versions of UNIX allow a process to create additional threads once it starts executing. Details of each running process are kept in the "Process Table".
UNIX is a multiprogramming and multiuser system, many processes may be running at the same time and many users may be using the system at once. Each user may have several active processes at once, so on a large system, there may be hundreds or thousands of processes running. In addition to these user processes there are also background processes, called daemons, are running. These are often started automatically when the system is booted. ('Daemon' supposedly stand for Disk and Execution Monitor but is also a variant spelling of 'demon'.) Pronounced "demon," this UNIX term refers to a specific type of program or agent designed to work in the background. Using a daemon, a program can simply give data to a daemon and go on to do other things. For example, a print daemon could handle print requests from multiple users and applications. The daemon understands about printers and print queues so that individual programs, and programmers, don't have to. Other examples of daemons are the cron daemon (control jobs that have to run regularly) and the mail daemon (usually sendmail, handles the delivery of mail).
Processes are created in UNIX in an simple but subtle manner. The fork() system call creates an exact copy of the original process. The process that calls fork() is called the parent process and the new process is called the child process. The parent and child are separate processes. If the parent subsequently changes any of its variables, the changes are not visible to the child, and vice versa. A nice idea, you often get to a point in a program where a job needs to be done but it's inconvenient to make your user wait until that job has finished. A good example of this is printing. Your user will be happy to press a Print button but unhappy to wait until the print job has finished before he or she can do something else. So you create a copy of the current program. One copy, the parent, carries on as normal whilst the other, the child, completes the print job and exits.
This sounds nice and simple (well, simple-ish!) - but as soon as you start to use fork() this question will occur to you: If the parent and child are identical how do you know which is which? Which one should run the parent code and which one should run the child code? The answer is that the fork system call returns a 0 to the child and the child's PID (Process IDentifier, a number) to the parent. This fragment of code demonstrates this, it's Perl code but very similar to the equivalent C code.
if($child_pid = fork()){
# if the child PID has been returned to me, then I'm the parent
print "Your file is being printed by process $child_pid.\n";
} else {
# if the child PID has NOT been returned to me, then I'm the child
PrintTheFile($current_file);
exit(0);
}
# the child never gets to here, so this is the parent
print "continuing....\n";
The system is designed so that a parent process can wait for a child process to finish, to check that all went well. To allow this to happen when a child process finishes its details are kept in the process table until the parent asks for it's exit details. Parent processes ask for these details by calling the wait() system call.
Child processes that have not yet been wait()ed for are called Zombie processes and their details appear in ps listings and other utilities (notably "top"). This often leads to concern that these processes are taking up system resources. It turns out that this is not the case. Each Zombie Process takes up an entry in the process list - but nothing else. Unless there are many Zombie Processes this will not be a problem.
Except for the first process, process zero, each process on a UNIX system is created using fork(). Process zero is created "by hand" when the system starts.
Open files are shared between parent and child. That is, if a file was open in the parent before the fork, it will continue to be open in both the parent and the child afterward. Changes made to the file by either one will be visible to the other. This behavior is only reasonable, because these changes are also visible to any unrelated process that opens the file as well. After the call to fork() the parent and child processes have separate file pointers, in other words they can move about in the file independantly of each other.
This site uses cookies to help personalise content, tailor your experience and to keep you logged in if you register.
By continuing to use this site, you are consenting to our use of cookies.