2024-09-23 16:01:31 +08:00

211 lines
6.0 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

# Runtime Interface
## 相关链接
参考示例:
- {{ '[helloworld]({}/src/examples/py/helloworld)'.format(code_site_root_path_url) }}
- {{ '[examples_py_helloworld_app_mode.py]({}/src/examples/py/helloworld/examples_py_helloworld_app_mode.py)'.format(code_site_root_path_url) }}
- {{ '[examples_py_helloworld_registration_mode.py]({}/src/examples/py/helloworld/examples_py_helloworld_registration_mode.py)'.format(code_site_root_path_url) }}
## 简介
与 CPP 接口不一样的是AimRT Python 接口只提供**App模式**,开发者需要自行管理 python 中的 main 方法,并在其中创建、管理 AimRT Core 实例。在**App模式**模式下AimRT Python 接口与 CPP 接口类似,提供了**注册**或**创建**这两种方式去开发用户的模块逻辑。
## AimRT Core
`aimrt_py`包中的`Core`类型用于控制 AimRT 实例的运行。该类型提供了以下几个关键的方法:
- `Initialize(core_options)`: 初始化 AimRT 运行时;
- `Start()`: 启动 AimRT 运行时,注意,该方法将阻塞当前线程,直到在其他线程中调用了`Shutdown`方法;
- `Shutdown()`: 停止 AimRT 运行时,支持重入;
- `RegisterModule(module)`: 注册一个模块;
- `CreateModule(module_name)->module_handle`: 创建一个模块;
前三个方法是 AimRT 实例的运行控制方法,后两个方法则对应了**注册**和**创建**这两种开发用户的模块逻辑的方式。其中,`Initialize`方法接收一个`CoreOptions`类型作为参数。此类型包含以下几个成员:
- `cfg_file_path`str配置文件路径
以下是一个简单的示例,该示例启动了一个 AimRT 运行时,但没有加载任何业务逻辑:
```python
import threading
import time
import aimrt_py
def main():
aimrt_core = aimrt_py.Core()
# init
core_options = aimrt_py.CoreOptions()
core_options.cfg_file_path = "path/to/cfg/xxx_cfg.yaml"
aimrt_core.Initialize(core_options)
# start
thread = threading.Thread(target=aimrt_core.Start)
thread.start()
# shutdown
time.sleep(1)
aimrt_core.Shutdown()
thread.join()
if __name__ == '__main__':
main()
```
## 注册模块
在注册模式下,开发者需要继承`ModuleBase`基类来创建一个自己的`Module`,并实现其中的`Initialize``Start`等方法,然后在`Core`实例调用`Initialize`方法之前将该`Module`注册到`Core`实例中。在此方式下仍然有一个比较清晰的`Module`边界。
关于`ModuleBase`基类的相关信息,请参考[ModuleBase](./module_base.md)文档。
以下是一个简单的例子,展示了如何编写一个自己的模块,并注册到`Core`实例中:
```python
import threading
import signal
import sys
import aimrt_py
import yaml
# 继承 aimrt_py.ModuleBase 实现一个Module
class HelloWorldModule(aimrt_py.ModuleBase):
def __init__(self):
super().__init__()
self.core = aimrt_py.CoreRef()
self.logger = aimrt_py.LoggerRef()
def Info(self):
info = aimrt_py.ModuleInfo()
info.name = "HelloWorldModule"
return info
def Initialize(self, core):
assert(isinstance(core, aimrt_py.CoreRef))
self.core = core
self.logger = self.core.GetLogger()
# log
aimrt_py.info(self.logger, "Module initialize")
return True
def Start(self):
aimrt_py.info(self.logger, "Module start")
return True
def Shutdown(self):
aimrt_py.info(self.logger, "Module shutdown")
global_aimrt_core = None
def signal_handler(sig, frame):
global global_aimrt_core
if (global_aimrt_core and (sig == signal.SIGINT or sig == signal.SIGTERM)):
global_aimrt_core.Shutdown()
return
sys.exit(0)
def main():
# 注册ctrl-c信号
signal.signal(signal.SIGINT, signal_handler)
signal.signal(signal.SIGTERM, signal_handler)
print("AimRT start.")
# 创建 aimrt_py.Core 实例
aimrt_core = aimrt_py.Core()
global global_aimrt_core
global_aimrt_core = aimrt_core
# 注册模块
module = HelloWorldModule()
aimrt_core.RegisterModule(module)
# 初始化 aimrt_py.Core 实例
core_options = aimrt_py.CoreOptions()
core_options.cfg_file_path = "path/to/cfg/xxx_cfg.yaml"
aimrt_core.Initialize(core_options)
# 启动 aimrt_py.Core 实例
thread = threading.Thread(target=aimrt_core.Start)
thread.start()
# 等待停止
while thread.is_alive():
thread.join(1.0)
aimrt_core.Shutdown()
global_aimrt_core = None
print("AimRT exit.")
if __name__ == '__main__':
main()
```
## 创建模块
`Core`实例调用`Initialize`方法之后,通过`CreateModule`可以创建一个模块,并返回一个句柄,开发者可以直接基于此句柄调用一些框架的方法,比如 RPC 或者 Log 等。在此方式下没有一个比较清晰的`Module`边界,一般仅用于快速做一些小工具。
以下是一个简单的例子,开发者需要编写的 Python 文件如下:
```python
import argparse
import threading
import time
import aimrt_py
import yaml
def main():
aimrt_core = aimrt_py.Core()
core_options = aimrt_py.CoreOptions()
core_options.cfg_file_path = "path/to/cfg/xxx_cfg.yaml"
aimrt_core.Initialize(core_options)
# create module handle
module_handle = aimrt_core.CreateModule("HelloWorldModule")
assert(isinstance(module_handle, aimrt_py.CoreRef))
# use cfg and log
module_cfg_file_path = module_handle.GetConfigurator().GetConfigFilePath()
with open(module_cfg_file_path, 'r') as file:
data = yaml.safe_load(file)
aimrt_py.info(module_handle.GetLogger(), str(data))
# start
thread = threading.Thread(target=aimrt_core.Start)
thread.start()
time.sleep(1)
# use log
count = 0
while(count < 10):
count = count + 1
aimrt_py.info(module_handle.GetLogger(), "Conut : {}.".format(count))
# shutdown
time.sleep(1)
aimrt_core.Shutdown()
thread.join()
if __name__ == '__main__':
main()
```