Classic Shell Scripting - Arnold Robbins [187]
A part of the operating-system kernel, called the scheduler, is responsible for managing process execution. When multiple CPUs are present, the scheduler tries to use them all to handle the workload; the human user should see no difference except improved response.
Processes are assigned priorities so that time-critical processes run before less important ones. The nice and renice commands can be used to adjust process priorities.
The average number of processes awaiting execution at any instant is called the load average. You can display it most simply with the uptime command:
$ uptime
Show uptime, user count, and load averages
1:51pm up 298 day(s), 15:42, 32 users, load average: 3.51, 3.50, 3.55
Because the load average varies continually, uptime reports three time-averaged estimates, usually for the last 1, 5, and 15 minutes. When the load average continually exceeds the number of available CPUs, there is more work for the system to do than it can manage, and its response may become sluggish.
Books on operating systems treat processes and scheduling in depth. For this book, and indeed, for most users, the details are largely irrelevant. All that we need in this chapter is a description of how to create, list, and delete processes, how to send signals to them, and how to monitor their execution.
Process Creation
One of the great contributions of Unix to the computing world is that process creation is cheap and easy. This encourages the practice of writing small programs that each do a part of a larger job, and then combining them to collaborate on the completion of that task. Because programming complexity grows much faster than linearly with program size, small programs are much easier to write, debug, and understand than large ones.
Many programs are started by a shell: the first word in each command line identifies the program to be run. Each process initiated by a command shell starts with these guarantees:
The process has a kernel context: data structures inside the kernel that record process-specific information to allow the kernel to manage and control process execution.
The process has a private, and protected, virtual address space that potentially can be as large as the machine is capable of addressing. However, other resource limitations, such as the combined size of physical memory and swap space on external storage, or the size of other executing jobs, or local settings of system-tuning parameters, often impose further restrictions.
Three file descriptors (standard input, standard output, and standard error) are already open and ready for immediate use.
A process started from an interactive shell has a controlling terminal, which serves as the default source and destination for the three standard file streams. The controlling terminal is the one from which you can send signals to the process, a topic that we cover later in Section 13.3.
Wildcard characters in command-line arguments have been expanded.
An environment-variable area of memory exists, containing strings with key/value assignments that can be retrieved by a library call (in C, getenv( )).
These guarantees are nondiscriminatory: all processes at the same priority level are treated equally and may be written in any convenient programming language.
The private address space ensures that processes cannot interfere with one another, or with the kernel. Operating systems that do not offer such protection are highly prone to failure.