模拟资源不可用性



我试图在simpy中使资源在一段时间内不可用。问题是超时,我发现资源仍然处于活动状态,并且在不可用的时间内提供服务。如果你遇到这样的问题,有人能帮我吗。非常感谢!

import numpy as np
import simpy
def interarrival():
return(np.random.exponential(10))
def servicetime():
return(np.random.exponential(20))

def servicing(env, servers_1):
i = 0
while(True):
i = i+1
yield env.timeout(interarrival())
print("Customer "+str(i)+ " arrived in the process at "+str(env.now))
state = 0
env.process(items(env, i, servers_array, state))
def items(env, customer_id, servers_array, state):
with servers_array[state].request() as request:
yield request
t_arrival = env.now
print("Customer "+str(customer_id)+ " arrived in "+str(state)+ "  at "+str(t_arrival))
yield env.timeout(servicetime())
t_depart = env.now
print("Customer "+str(customer_id)+ " departed from "+str(state)+ "  at "+str(t_depart))
if (state == 1):
print("Customer exists")
else:
state = 1
env.process(items(env, customer_id, servers_array, state))
def delay(env, servers_array):
while(True):
if (env.now%1440 >= 540 and env.now <= 1080):
yield(1080 - env.now%1440)
else:
print(str(env.now), "resources will be blocked")
resource_unavailability_dict = dict()
resource_unavailability_dict[0] = []
resource_unavailability_dict[1] = []
for nodes in resource_unavailability_dict:
for _ in range(servers_array[nodes].capacity):
resource_unavailability_dict[nodes].append(servers_array[nodes].request())
print(resource_unavailability_dict)
for nodes in resource_unavailability_dict:
yield env.all_of(resource_unavailability_dict[nodes])
if (env.now < 540):
yield env.timeout(540)
else:
yield env.timeout((int(env.now/1440)+1)*1440+540 - env.now)
for nodes in resource_unavailability_dict:
for request in resource_unavailability_dict[nodes]:
servers_array[nodes].release(request)
print(str(env.now), "resources are released")

env = simpy.Environment()
servers_array = []
servers_array.append(simpy.Resource(env, capacity = 5))
servers_array.append(simpy.Resource(env, capacity = 7))
env.process(servicing(env, servers_array))
env.process(delay(env,servers_array))
env.run(until=2880)

上面给出了代码。实际上,我有两个节点0和1,其中服务器容量分别为5和7。服务器在每天上午9点之前(午夜540分钟(和下午6点之后不可用。我正在尝试使用超时来创建不可用性,但没有工作。你能建议我如何修改代码以将其合并吗?

我得到了错误AttributeError: 'int' object has no attribute 'callbacks',我不知道为什么?

因此,简单资源的问题在于容量是只读属性。为了解决这个问题,你需要一些东西来抓住并控制资源。所以本质上,我有两种类型的用户;真正的工作;以及控制容量的那些。我使用的是一个简单的资源,这意味着在容量发生变化之前,将处理计划时间的队列。使用优先级资源意味着资源的当前用户可以在容量更改发生之前完成其进程,或者您可以使用先发制人的资源在计划的时间用资源中断用户。这是我的代码

"""
one way to change a resouce capacity on a schedule
note the the capacity of a resource is a read only atribute
Programmer: Michael R. Gibbs
"""
import simpy
import random
def schedRes(env, res):
"""
Performs maintenance at time 100 and 200
waits till all the resources have been seized 
and then spend 25 time units doing maintenace 
and then release
since I am using a simple resource, maintenance
will wait of all request that are already in 
the queue when maintenace starts to finish
you can change this behavior with a priority resource 
or pre-emptive resource
"""
# wait till first scheduled maintenance
yield env.timeout(100)
# build a list of requests for each resource
# then wait till all requests are filled
res_maint_list = []
print(env.now, "Starting maintenance")
for _ in range(res.capacity):
res_maint_list.append(res.request())
yield env.all_of(res_maint_list)
print(env.now, "All resources seized for maintenance")
# do maintenance
yield env.timeout(25)
print(env.now, "Maintenance fisish")
# release all the resources
for req in res_maint_list:
res.release(req)
print(env.now,"All resources released from maint")
# wait till next scheduled maintenance
dur_to_next_maint = 200 -env.now
if dur_to_next_maint > 0:
yield env.timeout(dur_to_next_maint)
# do it all again
res_maint_list = []
print(env.now, "Starting maintenance")
for _ in range(res.capacity):
res_maint_list.append(res.request())
yield env.all_of(res_maint_list)
print(env.now, "All resources seized for maintenance")
yield env.timeout(25)
print(env.now, "Maintenance fisish")
for req in res_maint_list:
res.release(req)
print(env.now,"All resources released from maint")

def use(env, res, dur):
"""
Simple process of a user seizing a resource 
and keeping it for a little while
"""
with res.request() as req:
print(env.now, f"User is in queue of size {len(res.queue)}")
yield req
print(env.now, "User has seized a resource")
yield env.timeout(dur)
print(env.now, "User has released a resource")
def genUsers(env,res):
"""
generate users to seize resources
"""
while True:
yield env.timeout(10)
env.process(use(env,res,21))

# set up 
env = simpy.Environment()
res = simpy.Resource(env,capacity=2) # may want to use a priority or preemtive resource
env.process(genUsers(env,res))
env.process(schedRes(env, res))
# start
env.run(300)

实现这一点的一种方法是使用抢占式资源。当资源不可用时,发出一堆优先级最高的请求,以占用空闲资源,并抢占当前正在使用的资源。然后,这些请求将在资源再次可用时释放资源。请注意,您需要添加一些逻辑,说明一旦资源再次可用,被抢占的进程将如何恢复。如果你不需要抢占进程,你可以只使用优先资源,而不是抢占资源

最新更新