Beruflich Dokumente
Kultur Dokumente
1 Introduction
Many operating systems rely upon processes either for their own structure or for the support of user tasks (or both). The final part of your previous module on Operating Systems considered a structure for an operating system based upon processes. The following examines the more general use of processes and in particular looks towards Unix1 for its examples. In the early stages, though, an attempt is made to generalise the principles involved in process organisation and operation with specific reference to Unix being made only when the fundamentals are clear. Systems exist that utilise either static processes or dynamic processes or both. Elsewhere in this module consideration of real-time environments makes use of static processes, each taking care of a particular part of the solution. It is more common, though, for systems to employ dynamic processes whereby processes are created and destroyed as necessary. The remainder of this document will concentrate upon dynamic processes.
P2
P3
P4
P5
P6
Once a process has been created it will, in the general case, run concurrently with its parent. System functions exist to allow a parent process to wait for a child process to complete, denoted by the child executing an exit operation, before it continues. This is, in effect, the opposite of the fork operation and produces a logical join. The execution of related parent and child processes following the aforementioned pattern may be viewed as follows:
1
Throughout the notes for this module, Unix should be taken to also refer to any flavour of Linux. Process Management 1 Colin H C Machin, January 2012
The fork operation requests that a child process be created and the two processes then execute concurrently. In the above example, the parent process is shown waiting for the child process to complete before the join is effected. The simultaneous existence of both the wait operation on the parents side and the exit operation on the childs marks the join. Once the child process has executed an exit operation, the system is free to dispose of the process, provided the parent has already reached the corresponding wait. If the child process executes an exit operation before the parents wait, the child process must not be disposed of; Unix uses the term zombie to refer to such processes that are no longer subject to scheduling but will be consuming resources such as memory. Note that wait and exit are system operations whereas the join is only a logical viewpoint, highlighted purely for the purpose of this description. When the child process is spawned it will inherit at least some of its parent's resources. In most systems, at least those that utilise segmentation, processes share with their parents the program memory area and any open files and channels. Of course, the child process will require its own data memory, but even this starts as a copy of the parent's data space. A table is provided in section 2.6 towards the end of this document detailing the manner in which resources and other attributes are inherited by processes under Unix. In addition to normal process termination, many systems allow premature termination of child processes. This abort operation is normally only available to the parent of the process in question. Should the parent of a process terminate, usually inadvertently, some systems allow the child process to continue whilst others will automatically terminate all of the child processes of the terminated parent. In the former case, the system inherits any orphans thus created. This is the preferred option as significant difficulties, such as those arising from files being left in an unexpected state, could ensue.
process might spawn a new process, this style of operation might be used when processing a tree structure of some sort. The parent process might fire off identical processes to deal with the left and right branches at a particular node, for example. Of course, without the benefits of multiple processors or, at least, multiple cores, the overhead of arranging to run two processes rather than one will outweigh any benefit. Much more commonly, a process spawns another so that the new process can perform some task that is totally unconnected with the processing being performed by the parent process. For example, in Unix all processes that run on behalf of a given user in order to process commands are spawned by that user's shell. Its sole purpose is to receive commands from the user and select the appropriate executable program to satisfy each command. At present, the only way that a process can be spawned is for the parent process - the shell in this case - to spawn a new process that is an exact copy of the shell process. This is insufficient in this situation; the requirement here is for the new process to change its identity immediately and take on the appearance of the program that will satisfy the user's command. Assume that the user wishes to receive a directory listing and therefore types the command ls. The shell must somehow organise that the ls program, held in one of the system directories (traditionally /bin), is loaded and run. The shell performs a fork operation in order to create a new process that will ultimately support the ls program's execution. The parent process continues to be the shell program, but the child process must change its identity to ls. It must request that the operating system throw away its current program and data areas and replace them with those specified for the ls program. In general terminology, this operation is known as an exec operation and at the 'C' programming level may be assumed to take a single parameter that specifies the location of the executable program's file. In the example chosen, the parent process would normally be required to wait for the child process to terminate before displaying the user prompt and awaiting a further command. Should, though, the user type an ampersand after the command name, this denotes that the program (process) is to run in background mode. In this case the shell would not issue a wait operation but would instead immediately display a new prompt to the user. In this case, it would be up to the user to handle the synchronisation of the completion of the new process with any other activity, as and when required. The user would in essence be testing for completion of the new process - in effect doing the same as the operating system's wait operation.
in terms of 'C' code, where it is likely that the top of stack carries the return value, this is seen to be the only difference between the parent's data memory and that of the child. This gives a clue as to the likely context of the fork operation. In terms of a 'C' program, the fork operation would typically appear as shown below.
if ((id = fork()) > 0) { | (parent's code) | } else { | (child's code) | }
It must be remembered that at the machine-code level, there will be a number of instructions that follow the one that actually marks the fork SVC, which will be executed by both the parent and the child. These are the instructions that contribute to returning from the function call, unloading the return code and the commencement of the 'C' if statement. It will only be as the if statement is processed that the parent and child process executions will diverge. However, viewing the operation from the 'C' code level is sufficiently detailed and equally instructive.
Process Management
Depending upon the precise manner in which the data defining a process is stored, this step may involve updating more than one physical table. 5. Enter the child's memory map into the process table. The only part of the process data relating to the child process that differs from that of the parent is the section that describes where the (data part of the) process is stored. 6. Choose a process id for the child. This must be unique and is usually the next available process number in order. 7. Inform the kernel and the filing system about the child process. This is so that they may both update their tables resulting in the scheduler being able to consider this process. 8. Report the child's memory map to the kernel. This step is necessary so that the kernel becomes aware of the revised memory allocations. 9. Drop the respective return codes into the parents and childs data memory. This allows the two processes to identify themselves and thus to distinguish the child from the parent.
This causes the operating system to replace the current code area for the child process with the code for the ls program, the detail of which is described in section 2.3.2. Note that the command argument -l does not form part of the string passed in the exec call. Instead, it is passed, as previously mentioned, in an argument to one of the specific versions of exec. The source of the shell program (parent process), then, will appear something like the following:
Process Management
Process Management
The output from two successive runs of this program is shown below. Note that the order of the output lines is different in the two cases. This demonstrates a certain level of randomness in process scheduling within Unix.
hpc% fork First fork ... Another fork ... Second child pid = 13820 First child pid = 13819 First wait ... pid = 13819, status = 0 Second wait ... pid = 13820, status = 0 hpc% fork First fork ... First child pid = 13878 Another fork ... First wait ... Second child pid = 13879 pid = 13879, status = 0 Second wait ... pid = 13878, status = 0 hpc%
The program is sufficiently short that the reader should, with minimal effort, be able to key it in and try it on any Unix system.
Process Management 7 Colin H C Machin, January 2012
In this example the pipe is used to transfer data only from the parent to the child as, since the pipe is only a one-way channel, the child process closes its write port and the parent process closes its read port. Executing the above program on hpc results in the output shown.
Process Management 8 Colin H C Machin, January 2012
hpc% pipe Received by child ... Hello there Child process complete hpc%
As before, the reader is encouraged to key in and try the above program.
Process Management