【问题标题】:Run an app and forget in a portable way以便携的方式运行应用程序并忘记
【发布时间】:2015-09-18 19:44:07
【问题描述】:

我正在编写一个从主程序调用的小型更新程序实用程序。主程序在调用后立即终止,并让更新程序复制所有更新的文件,然后它应该重新启动主程序。然而,最后一点开始让我头疼。

我可以用std::system(我知道,不安全,但可移植)运行程序就好了,但是更新程序只是挂在那里等待主程序完成。我一直在寻找使调用触发并忘记的方法,而线程似乎是最好的主意。

但是:

std::system("app");

在等待从system 返回时挂起更新程序。而这个:

std::thread(std::system, "app").detach();

也不是变体

std::thread t(std::system, "app");
t.detach();

似乎什么都做。但是当我加入线程时:

std::thread t(std::system, "app");
t.join();

它确实运行了应用程序,但仍然像在原始代码中一样等待它的返回。为什么分离的线程不能运行应用?

【问题讨论】:

  • 您需要什么级别的可移植性(即感兴趣的平台)?
  • @JasonR 主应用程序是一个 Qt 应用程序,我的目标是 3 个 Qt 平台:桌面、linux 和 mac...
  • QProcess 不合适吗?
  • @NicolasHolthaus 不幸的是,是的。我不能使用静态构建的 Qt,因此任何基于 Qt 的更新程序本身都会依赖于 Qt。因此,我需要关闭 Qt 应用程序(使用 QProcess 调用更新程序)并使用非 Qt 外部更新程序来完成工作并重新启动 Qt 应用程序或维护两个 Qt 部署(一个用于应用程序,一个用于updater) 并在更新时同时更新两者。我认为外部非 Qt 应用程序会是更好的解决方案。

标签: c++ multithreading stdthread


【解决方案1】:

任何线程,无论是否分离,都会在其进程完成时终止(在大多数系统上)。在更新程序结束执行之前给一些时间,线程也许能够真正进行调用:

#include <chrono>
#include <cstdlib>
#include <thread>

void do_app() {
  std::system("app");
}

int main() {
  std::thread(do_app).detach();
  std::this_thread::sleep_for(std::chrono::seconds(2));
} 

【讨论】:

  • 太棒了。 :-) 它确实起到了作用......我不认为这会是一个问题,因为我已经阅读了关于“主返回后分离线程会发生什么”的令人困惑的信息,其中一些声称它被杀死了(显然是这种情况) 有些不是。
  • 这是因为标准实际上并没有定义当主程序执行完成时分离线程会发生什么:每个系统都可以做任何事情。某些奇异的系统肯定有可能使线程保持执行。大多数人没有。
【解决方案2】:

我只会在不同的实现中使用 ifdef 块。对于 Windows,您可以使用 CreateProcess,Linux(可能还有 Mac)支持 POSIX popen / fork 方法。

std::system 并不能真正使您的程序具有可移植性,通常在 shell 上调用事物的语法因平台而异,最终您最终会得到与平台相关的代码。

这里有一个关于如何在 Linux 中做到这一点的详细教程: http://www.yolinux.com/TUTORIALS/ForkExecProcesses.html

对于 Windows: https://msdn.microsoft.com/en-us/library/windows/desktop/ms682425(v=vs.85).aspx

【讨论】:

  • 谢谢,我会调查的。调用更新程序时,通过从主程序调用实际命令来解决不同的调用方法。
猜你喜欢
  • 1970-01-01
  • 2020-02-10
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2023-03-30
  • 1970-01-01
  • 2011-02-09
  • 1970-01-01
相关资源
最近更新 更多