我希望有人可以帮我解决这个问题,或者至少指出我的方式错误......
作为我的问题的简单说明,考虑应用程序的一部分,您可以在其中进入"功能模式"操作状态.然后,取决于用户按下哪个功能键F1-F4,可以使用四个子模式.默认情况下,输入F1模式.状态图从如下开始:

用户可以随时按F1-F4切换到相应的模式.将这些转换添加到内部状态会导致以下情况:

显然这是(a)一团糟,(b)要定义的很多过渡.如果在某些时候我想添加一个F5Mode然后......好吧,你得到了图片.为避免这种情况,我想做以下事情:

Boost Statechart允许我定义从FunctionMode到任何内部状态的转换,但结果不是我所期望的.实际结果如下:

即按F1-F4切换模式会导致外部FunctionMode状态退出并重新进入,同时触发不需要的退出和进入操作.
早在2006年,图书馆作者和用户之间的这个线程似乎描述了同样的问题.我认为作者建议做以下工作:
然而,这种解决方法对我来说似乎并不吸引人:它已经添加了一个额外的状态级别来编译,代码变得不那么可读,深度历史将不得不用于返回任何功能模式子-states和中间状态对象不必要地被破坏并再次构造.
那么......我哪里错了?或者有哪些替代方案?我已经简要介绍了Boost Meta State Machine(msm),但从我到目前为止看到的情况来看,我更喜欢Statechart的外观.
我很惊讶更多的用户没有遇到同样的问题......这让我觉得我的方法可能完全错了!
我相信在使用 aiohttp ClientSession 请求时,我在长期存在的应用程序中发现了内存泄漏。如果按顺序等待每个发出请求的协程,那么一切似乎都很好。然而,并发运行时似乎存在请求上下文管理器对象的泄漏。
请考虑以下示例代码:
import logging
import tracemalloc
import asyncio
import aiohttp
async def log_allocations_coro():
while True:
await asyncio.sleep(120)
snapshot = tracemalloc.take_snapshot()
top_stats = snapshot.statistics('lineno')
str_list = [str(x) for x in top_stats[:5]]
logging.info("\n".join(str_list))
async def do_request():
try:
async with session.request("GET", "http://192.168.1.1") as response:
text = await response.text()
except:
logging.exception("Request failed")
async def main():
tracemalloc.start()
asyncio.ensure_future(log_allocations_coro())
timeout = aiohttp.ClientTimeout(total=1)
global session
session = aiohttp.ClientSession(timeout=timeout)
while True:
tasks = [ do_request(), do_request() ]
await asyncio.gather(*tasks)
await asyncio.sleep(2)
if __name__ == '__main__': …Run Code Online (Sandbox Code Playgroud)