What is a process and what is it made of?

The basic definition of a process is “a program in execution” (Silberschatz, Galvin, and Gagne, 2005, p. 82). A process is not the same as a program. A program contains a set of instructions stored on a disc. The process includes a copy of these instructions as well as a program counter, a stack for temporary data, and memory space for variables. It is important to remember that a single processor can only run one process at a time. To create the feel of multiple processes running simultaneously, the operating system must use some sort of process scheduling algorithm, which will be discussed further in section 3.0.
When a process is in execution it keeps track of its progress within the program code using a program counter. The program counter usually indicates the next instruction to be executed. When the processor switches to running a different process, this program counter is stored within the process so that when the processor starts to run this process again, it knows where in the program it left off.
According to Silberschatz, Galvin, and Gagne’s textbook, a process also has a stack to hold temporary data. Generally, this stack holds information about function calls, such as the function parameters and return address to return to after the function has completed. Variables are also stored within a process. Local variables are usually stored in the stack, while global variables are stored in a data section of the process (Silberschatz, Galvin, and Gagne, 2005, p. 82). Arrays and other collections are stored in “a heap, which is memory that is dynamically allocated during process run time” (Silberschatz, Galvin, and Gagne, 2005, p. 82).
Processes will generally have a state associated with them that is used to help with process scheduling. There are three main states of a process: running, ready, and waiting. When a process is created, it is set in its “ready” state. This means that the process is able to run at the current time. When the processor is actually executing instructions for a process, the process state is known as “running.” If a process is waiting for user input, a delay, or another external event to happen, it moves itself into a “blocked” or “waiting” state. This allows the processor to run other processes while it waits for the blocked process to be ready again. Figure 1 displays a state diagram of the three main process states along with conditions for state transitions.

Figure 1: State diagram of the three main process states (Tanenbaum and Woodhull, 2006, p. 61)

Only one process can be running at a time. When the processor switches to another process, the current process is set to the ready state and the next process changes to a running state. These transitions are illustrated by transitions 2 and 3, respectively, in Figure 1, above.
If a process requires user input, input from another process, or another external event, it will switch into a blocked state, as illustrated by transition 1 in Figure 1, above. In this state, the processor will not bother to execute the process, even if there are no other processes in the ready or running state. Once the external event has occurred, the process will transition into a ready state, as illustrated by transition 4 in Figure 1, above. At this point, the scheduler can decide when to set the process back to a running state again (Tanenbaum and Woodhull, 2006, p. 62).
To simulate process scheduling and synchronization algorithms, I have created a simple C# class based off the model of a process as described in this section. This class will be added onto and used in a console application throughout the report to demonstrate various concepts. The code for the basic class is as follows:

class Process
{
private string[] _sInstructions = null; //Program instructions
private int _iProgramCounter = 0; //Program Counter
private byte[] _byVariables = null; //Memory space for variables
//Temporary data for function calls
private struct FunctionCall
{
private byte[] byParameters;
private int iReturnAddress;
}
private Stack<FunctionCall> _stkFunctions = null; //Stack for temporary data
//Process state
public enum Estate {Ready, Running, Blocked}
private EState _State;
public EState State { get { return _State; } set { _State = value; } }
// Function name : Process (Constructor)
// Description : Construct a new process based off of a program
// Argument : string[] Program - The instructions of the program
public Process(string[] Program)
{
//Copy the program instructions to the process
_sInstructions = new string[Program.Length];
Program.CopyTo(_sInstructions, 0);
//Initialize program counter at the beginning of the instructions
_iProgramCounter = 0;
_State = EState.Ready;
//Allocate some space for variables (a real operating system would likely
//calculate the amount of space needed based on variables declared within
//the program)
_byVariables = new byte[1500];
//Initialize the program stack
_stkFunctions = new Stack<FunctionCall>();
}

// Function name : Tick
// Description : Execute a command of the process
// Return type : void
public void Tick()
{
//Get the instruction to execute
string sInstruction = _sInstructions[_iProgramCounter];

//Pretend to execute the command
Console.WriteLine("Executing command: " + sInstruction);

//Advance the program counter
++_iProgramCounter;
}
}

Any process management and scheduling will be demonstrated within the main program code. The simulated process scheduler will call the method Tick() to execute the next instruction within a process. The Tick() method will echo the instruction to the console and then advance the program counter. At this point, no instructions are actually decoded.
Because of the limits of the scope of this report, this simulated process will not be tested to its fullest extent. Since the instructions are simply being echoed and not actually executed, variables and the stack for temporary data will not be used.

                                       

User login