Machine Shop¶
Covers:
- Interrupts
- Resources
This example comprises a workshop with n identical machines. A stream of jobs (enough to keep the machines busy) arrives. Each machine breaks down periodically. Repairs are carried out by one repairman. The repairman has other, less important tasks to perform, too. Broken machines preempt theses tasks. The repairman continues them when he is done with the machine repair. The workshop works continuously.
A machine has two processes: working implements the actual behaviour of the machine (producing parts). break_machine periodically interrupts the working process to simulate the machine failure.
The repairman’s other job is also a process (implemented by other_job()
). The repairman itself is a Resource
with a capacity of 1
. The machine repairing has a priority of 1
, while the other job has a priority of 2
(the smaller the number, the higher the priority).
using SimJulia
using Distributions
const RANDOM_SEED = 23062015
const PT_MEAN = 10.0 # Avg. processing time in minutes
const PT_SIGMA = 2.0 # Sigma of processing time
const MTTF = 300.0 # Mean time to failure in minutes
const REPAIR_TIME = 30.0 # Time it takes to repair a machine in minutes
const JOB_DURATION = 30.0 # Duration of other jobs in minutes
const NUM_MACHINES = 10 # Number of machines in the machine shop
const WEEKS = 4 # Simulation time in weeks
const SIM_TIME = WEEKS * 7 * 24 * 60.0 # Simulation time in minutes
type Machine
name :: ASCIIString
parts_made :: Int
broken :: Bool
proc :: Process
function Machine(env::Environment, name::ASCIIString, repairman::Resource)
mach = new()
mach.name = name
mach.parts_made = 0
mach.broken = false
mach.proc = Process(env, name, working, mach, repairman)
Process(env, break_machine, mach)
return mach
end
end
function working(env::Environment, mach::Machine, repairman::Resource)
d = Normal(PT_MEAN, PT_SIGMA)
while true
done_in = abs(rand(d))
while done_in > 0.0
start = now(env)
try
yield(Timeout(env, done_in))
done_in = 0.0
catch(interrupted)
mach.broken = true
done_in -= now(env) - start
yield(Request(repairman, 1, true))
yield(Timeout(env, REPAIR_TIME))
yield(Release(repairman))
mach.broken = false
end
end
mach.parts_made += 1
end
end
function break_machine(env::Environment, mach::Machine)
d = Exponential(MTTF)
while true
yield(Timeout(env, rand(d)))
if !mach.broken
yield(Interrupt(mach.proc))
end
end
end
function other_jobs(env::Environment, repairman::Resource)
while true
done_in = JOB_DURATION
while done_in > 0.0
yield(Request(repairman, 2, false))
start = now(env)
try
yield(Timeout(env, done_in))
done_in = 0.0
yield(Release(repairman))
catch(preempted)
done_in -= now(env) - start
end
end
end
end
# Setup and start the simulation
println("Machine shop")
srand(RANDOM_SEED)
# Create an environment and start the setup process
env = Environment()
repairman = Resource(env, 1)
machines = [Machine(env, "Machine $i", repairman) for i = 1:NUM_MACHINES]
Process(env, other_jobs, repairman)
# Execute!
run(env, SIM_TIME)
# Analyis/results
println("Machine shop results after $WEEKS weeks")
for machine in machines
println("$(machine.name) made $(machine.parts_made) parts.")
end
The simulation’s output:
Machine shop
Machine shop results after 4 weeks
Machine 1 made 3258 parts.
Machine 2 made 3266 parts.
Machine 3 made 3264 parts.
Machine 4 made 3196 parts.
Machine 5 made 3286 parts.
Machine 6 made 3323 parts.
Machine 7 made 3233 parts.
Machine 8 made 3292 parts.
Machine 9 made 3201 parts.
Machine 10 made 3342 parts.