Skip to content

进程 API

dcc_mcp_core (process 模块)

跨平台 DCC 进程监控、生命周期管理和崩溃恢复。

概述

提供:

  • 进程监控 — 通过 PyProcessMonitor 实时资源使用(CPU、内存、状态)
  • DCC 启动 — 通过 PyDccLauncher 异步启动/终止/kill
  • 崩溃恢复 — 通过 PyCrashRecoveryPolicy 实现指数/固定退避重启策略
  • 后台监视 — 通过 PyProcessWatcher 事件轮询

PyProcessMonitor

使用 sysinfo 跟踪和查询进程资源使用。

构造函数

python
from dcc_mcp_core import PyProcessMonitor

monitor = PyProcessMonitor()

方法

方法返回描述
track(pid, name)None注册要监控的 PID
untrack(pid)None停止监控 PID
refresh()None刷新底层系统数据
query(pid)dict | None获取 PID 的快照
list_all()list[dict]获取所有跟踪 PID 的快照
is_alive(pid)bool检查 PID 是否在 OS 进程表中
tracked_count()int跟踪的 PID 数量

返回字典的键

类型描述
pidint进程 ID
namestr用户定义的名称
statusstr操作系统状态字符串
cpu_usage_percentfloatCPU 使用率 (0-100)
memory_bytesint内存使用(字节)
restart_countint重启计数

示例

python
import os
monitor = PyProcessMonitor()
monitor.track(os.getpid(), "self")
monitor.refresh()
info = monitor.query(os.getpid())
if info:
    print(f"CPU: {info['cpu_usage_percent']:.1f}%")
    print(f"内存: {info['memory_bytes'] / 1024 / 1024:.1f} MB")

PyDccLauncher

异步 DCC 进程启动器(启动/终止/kill)。

构造函数

python
from dcc_mcp_core import PyDccLauncher

launcher = PyDccLauncher()

方法

方法返回描述
launch(name, executable, args=None, launch_timeout_ms=30000)dict启动 DCC 进程
terminate(name, timeout_ms=5000)None优雅终止
kill(name)None强制杀死
pid_of(name)int | None按名称获取 PID
running_count()int活跃子进程数量
restart_count(name)int名称的重启计数

示例

python
info = launcher.launch(
    name="maya",
    executable="/usr/autodesk/maya/bin/maya",
    args=["-prompt", "-batch"],
    launch_timeout_ms=30000,
)
print(f"已启动 PID: {info['pid']}")

# 终止
launcher.terminate("maya", timeout_ms=5000)

PyCrashRecoveryPolicy

DCC 进程的崩溃恢复策略。

构造函数

python
from dcc_mcp_core import PyCrashRecoveryPolicy

policy = PyCrashRecoveryPolicy(max_restarts=3)

属性

属性类型描述
max_restartsint最大重启次数(构造函数参数,默认 3)

方法

方法返回描述
use_exponential_backoff(initial_ms, max_delay_ms)None使用指数退避
use_fixed_backoff(delay_ms)None使用固定延迟
should_restart(status)bool检查状态是否需要重启
next_delay_ms(name, attempt)int获取尝试前的延迟

示例

python
policy = PyCrashRecoveryPolicy(max_restarts=3)
policy.use_exponential_backoff(initial_ms=1000, max_delay_ms=30000)

if policy.should_restart("crashed"):
    delay = policy.next_delay_ms("maya", attempt=0)
    print(f"在 {delay}ms 后重启...")

支持的状态值

状态描述
"crashed"进程崩溃
"unresponsive"进程无响应

PyProcessWatcher

带事件轮询的异步后台进程监视器。

构造函数

python
from dcc_mcp_core import PyProcessWatcher

watcher = PyProcessWatcher(poll_interval_ms=500)

方法

方法返回描述
track(pid, name)None注册要监控的 PID
untrack(pid)None停止监控 PID
start()None启动后台监视循环
stop()None停止后台监视循环
poll_events()list[dict]排出待处理事件
is_running()bool检查循环是否运行
tracked_count()int跟踪的 PID 数量

事件类型

事件字典包含: type, pid, name

事件类型额外字段
heartbeatnew_status, cpu_usage_percent, memory_bytes
status_changedold_status, new_status
exited

示例

python
import os, time
watcher = PyProcessWatcher(poll_interval_ms=200)
watcher.track(os.getpid(), "self")
watcher.start()

time.sleep(0.5)

for event in watcher.poll_events():
    print(f"事件: {event['type']} - {event['name']}")

watcher.stop()

集成示例

自动重启 DCC

python
import time
from dcc_mcp_core import PyDccLauncher, PyProcessWatcher, PyCrashRecoveryPolicy

launcher = PyDccLauncher()
watcher = PyProcessWatcher(poll_interval_ms=500)
policy = PyCrashRecoveryPolicy(max_restarts=5)
policy.use_exponential_backoff(initial_ms=1000, max_delay_ms=30000)

info = launcher.launch(name="maya", executable="/usr/bin/maya")
watcher.track(info["pid"], "maya")
watcher.start()

while True:
    events = watcher.poll_events()
    for event in events:
        if event["type"] == "exited":
            if policy.should_restart("crashed"):
                delay = policy.next_delay_ms("maya", attempt=0)
                time.sleep(delay / 1000)
                info = launcher.launch(name="maya", executable="/usr/bin/maya")
                watcher.track(info["pid"], "maya")
    time.sleep(0.1)

GUI 可执行文件探测(issue #524)

DCC 适配器在派生子进程前需要回答两个问题:这个路径是会弹窗的 GUI 二进制吗? 以及是否有 headless 的 Python 兄弟应该优先使用?。下面两个工具函数加上 GuiExecutableHint 把这套逻辑从每个插件的 server.py 抽到 dcc_mcp_core 内部的厂商表。

导出符号: is_gui_executablecorrect_python_executableGuiExecutableHint

is_gui_executable

python
is_gui_executable(path: str) -> GuiExecutableHint | None

对照内置 DCC 表探测 path。Python 解释器(python.exemayapyhython …) 和未知厂商二进制返回 None

python
from dcc_mcp_core import is_gui_executable

hint = is_gui_executable(r"C:\Program Files\Autodesk\Maya2024\bin\maya.exe")
if hint is not None:
    print(hint.dcc_kind)               # "maya"
    print(hint.recommended_replacement) # PosixPath('.../bin/mayapy.exe')

correct_python_executable

python
correct_python_executable(path: str) -> pathlib.Path

如果 path 是已知的 DCC GUI 二进制并且磁盘上存在 headless-Python 兄弟, 则返回兄弟路径;否则原样返回。一行修正派生 launcher 子进程前 DCC_MCP_PYTHON_EXECUTABLE 的便捷 API:

python
import os
from dcc_mcp_core import correct_python_executable

os.environ["DCC_MCP_PYTHON_EXECUTABLE"] = str(
    correct_python_executable(os.environ.get("DCC_MCP_PYTHON_EXECUTABLE", ""))
)

GuiExecutableHint

is_gui_executable 返回的不可变值类型,用户不可实例化。

属性类型描述
gui_pathpathlib.Path被探测的路径
dcc_kindstrDCC 家族名("maya""houdini""unreal""blender""3dsmax" …)
recommended_replacementpathlib.Path | None磁盘上解析到的 headless 兄弟,找不到为 None

dcc_kind 是稳定的 wire 字符串 —— 适配器可以据此切换 skill 作用域 (例如仅当 dcc_kind == "maya" 时自动加载 maya/* skill)。

Released under the MIT License.