2015-02-05 16 views
0

나는 simpy에서 기차 시뮬레이션을하고 있으며, 아래의 코드에 따라 하나의 기차 엔티티로 지금까지 성공을 거두었습니다.Simpy 지하철 시뮬레이션 : 리소스 대기열에서 클래스 기차의 인터럽트 장애를 수정하는 방법은 무엇입니까?

기차 프로세스는 플랫폼이 따르는 섹션입니다. 각 구간과 플랫폼에는 한 번에 열차 하나만 활용할 수 있도록 1의 자원이 있습니다. 나는 아래의 오류 주위에 얻을 수있는 방법을 찾을 수 없습니다 그러나

: 나는 시뮬레이션에 두 번째 기차에 추가 할 때

때때로 상황이있는 곳 다음 자원을 사용할 수와 실패에 대한 하나 명의 열차 대기 그것이 기다리는 동안 그 열차에서 발생합니다.

내가 결국 인터럽트 : Interrupt() 오류로 끝납니다.

리소스에 대해 이러한 실패한 큐 주위에 방법이 있습니까?

도움을 주시면 감사하겠습니다.

import random 
import simpy 
import numpy 

# Configure parameters for the model 
RANDOM_SEED = random.seed() # makes results repeatable 

T_MEAN_SECTION = 200.0 # journey time (seconds) 

DWELL_TIME = 30.0 # dwell time mean (seconds) 
DWELL_TIME_EXPO = 1/DWELL_TIME # for exponential distribution 

MTTF = 600.0 # mean time to failure (seconds) 
TTF_MEAN = 1/MTTF # for exponential distribution 

REPAIR_TIME = 120.0 # mean repair time for when failure occurs (seconds) 
REPAIR_TIME_EXPO = 1/REPAIR_TIME # for exponential distribution 

NUM_TRAINS = 2 # number of trains to simulate 

SIM_TIME_HOURS = 1 # sim time in hours 
SIM_TIME_DAYS = SIM_TIME_HOURS/18.0 # number of days to simulate 
SIM_TIME = 3600 * 18 * SIM_TIME_DAYS # sim time in seconds (this is used in the code below) 


# Defining the times for processes 
def Section(): # returns processing time for platform 7 Waterloo to 26 Bank 
    return T_MEAN_SECTION 

def Dwell(): # returns processing time for platform 25 Bank to platform 7 Waterloo 
    return random.expovariate(DWELL_TIME_EXPO) 

def time_to_failure(): # returns time until next failure 
    return random.expovariate(TTF_MEAN) 



# Defining the train 
class Train(object): 

    def __init__(self, env, name, repair): 
     self.env = env 
     self.name = name 
     self.trips_complete = 0 
     self.num_saf = 0 
     self.sum_saf = 0 
     self.broken = False 

    # Start "running" and "downtime_train" processes for the train 
     self.process = env.process(self.running(repair)) 
     env.process(self.downtime_train()) 


    def running(self, repair): 

     while True: 

      # request section A 
      request_SA = sectionA.request() 

########## SIM ERROR IF FAILURE OCCURS HERE ########### 
      yield request_SA 

      done_in_SA = Section()   
      while done_in_SA: 

       try: 
        # going on the trip 
        start = self.env.now 


        print('%s leaving platform at time %d') % (self.name, env.now) 

        # processing time 
        yield self.env.timeout(done_in_SA) 

        # releasing the section resource 
        sectionA.release(request_SA) 
        done_in_SA = 0 # Set to 0 to exit while loop 

       except simpy.Interrupt: 
        self.broken = True 
        delay = random.expovariate(REPAIR_TIME_EXPO) 
        print('Oh no! Something has caused a delay of %d seconds to %s at time %d') % (delay, self.name, env.now) 
        done_in_SA -= self.env.now - start # How much time left? 
        with repair.request(priority = 1) as request_D_SA: 
         yield request_D_SA 
         yield self.env.timeout(delay) 
        self.broken = False 
        print('Okay all good now, failure fixed on %s at time %d') % (self.name, env.now) 
        self.num_saf += 1 
        self.sum_saf += delay 



      # request platform A 
      request_PA = platformA.request() 

########## SIM ERROR IF FAILURE OCCURS HERE ########### 
      yield request_PA 

      done_in_PA = Dwell() 
      while done_in_PA: 

       try: 

        # platform process 
        start = self.env.now 


        print('%s arriving to platform A and opening doors at time %d') % (self.name, env.now) 
        yield self.env.timeout(done_in_PA) 
        print('%s closing doors, ready to depart platform A at %d\n') % (self.name, env.now) 
        # releasing the platform resource 
        platformA.release(request_PA) 
        done_in_PA = 0 # Set to 0 to exit while loop 

       except simpy.Interrupt: 
        self.broken = True 
        delay = random.expovariate(REPAIR_TIME_EXPO) 
        print('Oh no! Something has caused a delay of %d seconds to %s at time %d') % (delay, self.name, env.now) 
        done_in_PA -= self.env.now - start # How much time left? 
        with repair.request(priority = 1) as request_D_PA: 
         yield request_D_PA 
         yield self.env.timeout(delay) 
        self.broken = False 
        print('Okay all good now, failure fixed on %s at time %d') % (self.name, env.now) 
        self.num_saf += 1 
        self.sum_saf += delay 


     # Round trip is finished 

      self.trips_complete += 1 


# Defining the failure event   
    def downtime_train(self): 
     while True: 
      yield self.env.timeout(time_to_failure()) 
      if not self.broken: 
      # Only break the train if it is currently working 
       self.process.interrupt() 



# Setup and start the simulation 
print('Train trip simulator') 
random.seed(RANDOM_SEED) # Helps with reproduction 

# Create an environment and start setup process 
env = simpy.Environment() 

# Defining resources 
platformA = simpy.Resource(env, capacity = 1) 
sectionA = simpy.Resource(env, capacity = 1) 

repair = simpy.PreemptiveResource(env, capacity = 10) 

trains = [Train(env, 'Train %d' % i, repair) 
    for i in range(NUM_TRAINS)] 


# Execute 
env.run(until = SIM_TIME) 

답변

1

프로세스가 리소스를 요청하고 결코 해제하지 않습니다. 그래서 두 번째 열차가 성공하기위한 요청을 영원히 기다립니다. 기다리는 동안 오류 프로세스가 프로세스를 방해하는 것 같습니다. 그래서 당신은 오류가 발생합니다. SimPy의 리소스가 어떻게 작동하는지, 특히 작업이 완료되면 리소스를 해제하는 방법을 이해하려면 guide to resources을 읽어보십시오.

+0

답장을 보내 주셔서 감사합니다. 그러나 리소스는 while try : 요청 된 부분 아래 부분에서 해제됩니다. 이것은 열차가 루프에서 두 프로세스를 멋지게 돌아 다니면서 잘 작동하는 것 같습니다. 열차 중 하나에서 오류가 발생할 때까지 리소스 대기열에 들어 있습니다. – bobo

+0

좋아요, 이제 어디서 요청을 풀 수 있는지 알 수 있습니다. 문제는 열차가 request_SA 또는 request_PA를 기다리는 동안 장애 프로세스에 의해 중단된다는 것입니다. 'yield ... '를'try ... except simpy.Interrupt : pass'와 함께 감싸서 무시할 수 있습니다. –

+0

문제를 완벽하게 해결해 주셔서 감사합니다! – bobo