Simpy 3:在没有'with...as:'的情况下使用Resources.Resource.request()/.release()
我正在尝试在我正在做的项目中添加SimPy模拟,但对版本3的请求有些困惑。
我能够顺利地使用'with'语句来实现资源的管理,但在我的情况下,我想在不使用'with'语句的情况下请求和释放资源。
然而,我找不到使用SimPy 3的相关示例。我阅读了关于资源的文档和源代码,但还是没能完全搞明白。有人能解释一下如何正确地:
...
Request a Resource with the method: 'request()'
...
Release that Resource with the method: 'release()'
...
谢谢,抱歉打扰了。
PS:我打算使用Resources.resource。
3 个回答
0
这一切都在 PEP343 中有详细说明;
with EXPR as VAR:
BLOCK
变成:
mgr = (EXPR)
exit = type(mgr).__exit__ # Not calling it yet
value = type(mgr).__enter__(mgr)
exc = True
try:
try:
VAR = value # Only if "as VAR" is present
BLOCK
except:
# The exceptional case is handled here
exc = False
if not exit(mgr, *sys.exc_info()):
raise
# The exception is swallowed if exit() returns true
finally:
# The normal and non-local-goto cases are handled here
if exc:
exit(mgr, None, None, None)
这就是 Python 如何使用 with... as...
语句的方式,但我猜想你有某种原因不想使用这些。如果是这样的话,你只需要 __enter__
和 __exit__
这两个函数。我理解的方式是,__enter__
用来设置一切,而 __exit__
则负责清理工作。
3
使用 with
语句时,当你进入 with
块时,会调用 __enter__
方法,而当你离开这个块时,会调用 __exit__
方法。所以当你写
res = resource.Resource()
with res.request() as req:
# stuff
实际上是在对一个请求对象调用 __enter__
方法,然后执行 #stuff
,最后再调用 __exit__
方法:
class Request(base.Put):
def __exit__(self, exc_type, value, traceback):
super(Request, self).__exit__(exc_type, value, traceback)
self.resource.release(self)
class Put(Event): # base.Put
def __enter__(self):
return self
def __exit__(self, exc_type, exc_value, traceback):
# If the request has been interrupted, remove it from the queue:
if not self.triggered:
self.resource.put_queue.remove(self)
因此,with
块可以看作是这样的:
res = resource.Resource(...)
req = res.request()
#stuff
if not req.triggered:
res.put_queue.remove(req)
res.release(req)
不过,with
块还有一个好处,就是无论在执行 #stuff
的过程中发生什么异常,它都会确保清理代码被执行。而如果用上面的代码,就没有这个保障了。
6
如果你想在没有with
块的情况下使用某个资源(而且你知道不会被打断),那么你只需要这样做:
req = resource.request()
yield req
# do stuff
resource.release(req)