在 SimPy 中,我想要模拟一种服务时间依赖于某个函数计算复杂度的情况。在这个模拟中,服务请求的到达不应该因为函数的处理而停止。为了测试,我使用了一个示例函数,该函数利用 CPU 进行几秒钟的处理:
sorted([float(random.random()) for i in range(1000000)])
我想调用这个函数来模拟服务,但不要阻止新的服务请求到达。如果我调用这个函数,新的服务请求只会在函数执行之后到达,而不是在指定的时间到达。
def visit(self, timeAtNAT, res):
arrive=time.clock()-startTime
print("%7.4f. Packet #%s arrived." % (time.clock()-startTime, self.name))
yield request, self, res
wait = time.clock()-startTime - arrive
print("%7.4f. Packet #%s waited %6.3f" % (time.clock()-startTime, self.name, wait))
sorted([float(random.random()) for i in range(1000000)])
yield release, self, res
print("%7.4f. Packet #%s left" % (time.clock()-startTime, self.name))
因此,在我的示例中,新的数据包只有在前一个数据包离开后才能到达。我尝试使用了多进程,但是我遇到了命名冲突(Process 类)。我对 SimPy、并行编程和 Python 都是新手。
2、解决方案
为了解决这个问题,我们可以使用 SimPy 中的 hold 函数。hold 函数可以暂停一个进程一段时间,而不会阻止其他进程的执行。我们可以将 hold 函数与示例函数结合起来,创建一个新的函数,用来模拟服务时间:
def service(timeAtNAT, res):
arrive=time.clock()-startTime
print("%7.4f. Packet #%s arrived." % (time.clock()-startTime, self.name))
yield request, self, res
wait = time.clock()-startTime - arrive
print("%7.4f. Packet #%s waited %6.3f" % (time.clock()-startTime, self.name, wait))
yield hold, time.clock()-startTime + 5
yield release, self, res
print("%7.4f. Packet #%s left" % (time.clock()-startTime, self.name))
在这个新的函数中,我们使用了 hold 函数来暂停进程 5 秒钟。这模拟了函数的处理时间。在暂停期间,其他进程可以继续执行。
然后,我们可以使用这个新的函数来模拟服务:
for i in range(10):
env.process(visit(i, resource))
在这个例子中,我们创建了 10 个进程,每个进程模拟一个服务请求。这些进程将在 5 秒钟内同时执行,而不会互相阻塞。
代码例子:
import simpy
import random
# 创建一个 SimPy 环境
env = simpy.Environment()
# 创建一个资源
resource = simpy.Resource(env, capacity=1)
# 定义一个服务函数
def service(timeAtNAT, res):
arrive=time.clock()-startTime
print("%7.4f. Packet #%s arrived." % (time.clock()-startTime, self.name))
yield request, self, res
wait = time.clock()-startTime - arrive
print("%7.4f. Packet #%s waited %6.3f" % (time.clock()-startTime, self.name, wait))
yield hold, time.clock()-startTime + 5
yield release, self, res
print("%7.4f. Packet #%s left" % (time.clock()-startTime, self.name))
# 创建 10 个进程,每个进程模拟一个服务请求
for i in range(10):
env.process(service(i, resource))
# 运行模拟
env.run()
在这个例子中,我们创建了一个 SimPy 环境、一个资源和一个服务函数。然后,我们创建了 10 个进程,每个进程模拟一个服务请求。这些进程将在 5 秒钟内同时执行,而不会互相阻塞。