首页 > 解决方案 > QProcess 启动时如何管理资源?

问题描述

语境

我正在尝试为我们的应用程序实现一种编排器模式。

基本上,我们在 Qt 中开发了三个不同且独立的应用程序,它们使用 Web Socket 相互通信。我们称它们为“核心”、“业务”和“用户界面”。这是一个灵活的目标,因为我们可以简单地以更适合的技术开发新应用程序,并通过相同的通信协议将其连接到其他应用程序。

现在的想法是有一个简单的启动器,它允许我们指定要启动的部分。我们启动这个“类似协调器”的应用程序,它从一个配置文件启动所有必需的进程。

目前一切都在 Qt 中完成(用于 UI 界面的 QML)。


创刊号

我创建了一个自定义类,用于读取配置文件、准备流程并使用它们各自的参数启动它们。

这在配置文件中使用了与它们的名称相关的一个并使用方法启动std::map它们。QProcessQProcess::start(<process_path>)

问题是直到最近一切都很顺利。子进程启动并完美运行;一切都照常进行,直到我们到达某个点是“ui”部分崩溃(通常是LLVM 内存错误vector::length 错误)。

起初我们考虑内存泄漏或代码错误,但经过大量调试后,我们发现当我们单独运行每个部分(不使用自定义协调器类)时,应用程序没有任何错误。


问题/疑虑

所以,我们的问题是:该QProcess:start()方法是否实际上与其父方法共享相同的堆栈?三个具有相同父进程的进程,每个应用程序中存储的约 500 个元素的向量在返回时可能超过堆栈大小也就不足为奇了。

信息

我们使用 MacOS Big Sur,IDE 是 Qt Creator,使用 Qt 5.15.0 和 C++11。

尝试使用 valgrind,但如阅读herehere,现在这似乎是一个死胡同。在应用程序退出后的 .crash 文件中可以看到以下错误。

还尝试重定向或完全删除应用程序的输出。setProcessChannelMode首先在启动应用程序时更改,然后使用startDetached而不是启动。然后,注释我的 Log 方法将日志信息转储到相应的 Qt 输出(info/warning/critical/fatal/debug)。

正如@stanislav888 所建议的那样,我们可以在 bash 脚本中重写应用程序管理器部分,这可能会奏效,但我想了解根本问题以避免将来出现错误。

标签: qtc++11memory-leaksqt5qprocess

解决方案


它看起来像一个糟糕的设计。通过 bash 或 PowerShell 脚本运行和编排的应用程序看起来要好得多。但不管怎么说。

  1. 您可以尝试抑制编排的应用程序输出,看看会发生什么。程序输出可能会淹没内存并导致崩溃。
  2. 您必须检查导致崩溃的特定故障。使用内存“coredump”和系统错误消息来了解所有问题的详细信息。我确信社区需要这些细节。因为“оout of memory”、“stack depth exceeded”和相同的错误会产生很大的不同。
  3. 尝试编写与 Qt 应用程序执行相同工作流程的 bash 或 PowerShell 脚本。希望不难。但它会帮助你找出问题所在。至少您可以从应用程序运行此脚本。

推荐阅读