抱歉,您的浏览器无法访问本站
本页面需要浏览器支持(启用)JavaScript
了解详情 >

SimPy Monitoring

Monitor processes

在一个或多个状态变量每次更改时或以离散的间隔监视它们的值,并将其存储在某个位置(例如,内存、数据库或文件中)

在以下例子中,只需使用一个列表,并在每次更改时附加所需的值。

如果要监视多个变量,可以将 (named)tuples 附加到数据列表中。

如果将数据存储在 NumPy 数组或数据库中,可以通过将数据缓冲在 Python 列表中,并且只向数据库写入较大的块(或完整的数据集)。

Resource usage

资源的监视有很多种可能的情况,比如:

  • 一段时间内的资源利用率,

    • 一次使用资源的进程数
    • container 的 level
    • store 中的 item 数量

    这可以在离散的时间步长中进行监控,也可以在每次发生变化时进行监控

  • 一段时间内(put | get)队列中的进程数(以及平均值)。也可以在离散的时间步长或每次发生变化时进行监控

  • 对于 PreemptiveResource,可能需要测量一段时间内发生抢占的频率

没有直接的访问资源的代码,但可以通过 Monkey-patching 方法收集。

以下是一个示例,演示了如何向在 get/requestput/release 事件之前或之后被调用的资源添加回调:

from functools import partial, wraps
import simpy

def patch_resource(resource, pre=None, post=None):
    """Patch *resource* so that it calls the callable *pre* before each
    put/get/request/release operation and the callable *post* after each
    operation.  The only argument to these functions is the resource
    instance.

    """
    def get_wrapper(func):
        # Generate a wrapper for put/get/request/release
        @wraps(func)
        def wrapper(*args, **kwargs):
            # This is the actual wrapper
            # Call "pre" callback
            if pre:
                pre(resource)

            # Perform actual operation
            ret = func(*args, **kwargs)

            # Call "post" callback
            if post:
                post(resource)

            return ret
        return wrapper

    # Replace the original operations with our wrapper
    for name in ['put', 'get', 'request', 'release']:
        if hasattr(resource, name):
            setattr(resource, name, get_wrapper(getattr(resource, name)))

def monitor(data, resource):
    """This is our monitoring callback."""
    item = (
        resource._env.now,  # The current simulation time
        resource.count,  # The number of users
        len(resource.queue),  # The number of queued processes
    )
    data.append(item)

def test_process(env, res):
    with res.request() as req:
        yield req
        yield env.timeout(1)

env = simpy.Environment()

res = simpy.Resource(env, capacity=1)
data = []
# Bind *data* as first argument to monitor()
# see https://docs.python.org/3/library/functools.html#functools.partial
monitor = partial(monitor, data)
patch_resource(res, post=monitor)  # Patches (only) this resource instance

p = env.process(test_process(env, res))
env.run(p)

print(data)

查看一次有多少个 processes 在等待同一个资源:

Event tracing

跟踪事件的创建、触发和处理时间,哪个进程创建了事件,哪些进程等待了事件。

  • Environment.step():处理所有事件
  • Environment.schedule():安排所有事件、插入 SimPy 事件队列中

Environment.step() 跟踪所有处理的事件:




SimPy 学习




本站采用 Volantis 主题设计