In the PLT Scheme Simulation Collection, a process encapsulates an event that executes the body of the process; provides state information for the process;and, most importantly, provides a handle that allows the process to interact with other simulation elements (e.g. resources or other processes).
Defines a new process with the specified name. Syntactically, the macro is the same as define for a function – indeed, an unnamed procedural object us created and associated with the process. However, the simulation collection maintains references to process objects, thus allowing them to interact with each other and other simulation elements.
The symbol name is bound to the process definition for the process. This is used in creating process instances.
The variable self is bound to the process instance during the execution of a process.
|(struct process (process-def|
|state : integer?|
Represents a process instance.
process-def – points to a structure that contains information from the process definition needed internally by the simulation collection.
event – contains the event object that represents the execution of the body of the process.
state – maintains the state of the process.
Note that there are other fields used for continuous processes. These are described in Chapter 10 Continuous Simulation Models.
There are a few short-cut functions that return information from the other structures pointed to by a processes.
|( process) → symbol?|
Returns the name of the process.
|( process) → (>=/c 0.0)|
Returns the time of the next event associated with process. This is the value of the time fiels of the event field of process. This is useful in simulations using the interrupt abd resume advanced simulation control functions.
|( process time) → any|
|time : (>=/c 0.0)|
Sets the time of the next event associated with process. It sets the value of the time fiels of the event field of process. This is useful in simulations using the interrupt abd resume advanced simulation control functions.
The normal way to create a process is using the macro as described in Section 4.1 Scheduling Events and Processes. This creates and schedules a process for execution.
|( process-def arguments) →|
|arguments : (listof any?)|
Creates a new instance of the process whose definition is process-def. The process instance event will have it’s function field set to the body function for the process with the specified arguments. The process instance is not added to an event list and remains in the PROCESS-CREATED state.
Each process instance is in a specific state ar amy point in its life. The current state is available using the function. The process states are:
PROCESS-TERMINATED – the body of the process has finished execution.
PROCESS-CREATED – the process has been created, but the body of the process has not begun executing. If the process instance was created using the macro, the initial execution of the body of the process is scheduled, but has not yet executed.
PROCESS-ACTIVE – the body of the process is executing.
PROCESS-WAITING/WORKING – the process is current in a .
PROCESS-WORKING-CONTINUOUSLY – the process is currently in a .
PROCESS-DELAYED – the process is delayed waiting for a resource.
PROCESS-INTERRUPTED – the process has been interrupted by another process via an interrupt call.
PROCESS-SUSPENDED – the process has suspended itself via a suspend call.
This example is the same as the simulation model in Chapter 5. Indeed, the only syntactic difference is the use of instead of define for the generator and customer processes.
|; Example 1 - Processes|
|(require (planet williams/simulation/simulation))|
|(require (planet williams/science/random-distributions))|
|( (generator n)|
|(for ((i (in-range n)))|
|( (random-exponential 4.0))|
|( now (customer i))))|
|( (customer i)|
|(printf "~a: customer ~a enters~n"|
|( (random-flat 2.0 10.0))|
|(printf "~a: customer ~a leaves~n"|
|(define (run-simulation n)|
|( (at 0.0) (generator n))|
Produces the following output.
|0.6153910608822503: customer 0 enters|
|5.599485116393393: customer 1 enters|
|6.411843645405005: customer 2 enters|
|8.48917994426752: customer 0 leaves|
|10.275428842274628: customer 1 leaves|
|14.749397986170655: customer 2 leaves|
|23.525886616767437: customer 3 enters|
|27.18604340910279: customer 3 leaves|
|32.1644631797164: customer 4 enters|
|33.14558760001698: customer 5 enters|
|39.67682614849173: customer 4 leaves|
|40.486553934113665: customer 6 enters|
|41.168084930967424: customer 5 leaves|
|45.72670063299798: customer 6 leaves|
|46.747675912143016: customer 7 enters|
|49.212327970772435: customer 8 enters|
|50.556538752352886: customer 9 enters|
|51.46738784004611: customer 8 leaves|
|52.514846525674855: customer 7 leaves|
|56.11635302397275: customer 9 leaves|
A few things to note at this point are:
The output of this example is identical to that of the example in Section 5.3 Example – Functions as Events.
For many simple processes, an event may be used instead. Events are lighter-weight than processes. For example, in subsequent simulation models we will use an event for the generator function since it does not require any interaction with other processes – other than scheduling the customer processes.