【问题标题】:Launch Executable from Secondary thread从辅助线程启动可执行文件
【发布时间】:2014-03-02 08:21:39
【问题描述】:

我需要一种从辅助线程启动可执行文件(进程)的方法。据我所知,我使用的 wxWidgets 工具包没有给我任何方法,现在我必须寻求依赖于平台的方法(仅限 Linux 和 Windows)方法来做到这一点。

可执行文件将读取和写入文件。除了知道进程是否仍在运行(以及可能的退出代码)之外,该线程与进程本身没有多大关系。进程终止后,线程将读取写入的文件,对其进行分析并将结果发送给GUI线程进行显示。我不知道该怎么做,因为我一直依赖wxExecute

【问题讨论】:

标签: c++ multithreading ipc wxwidgets


【解决方案1】:

您真的想要单独的进程,还是线程会这样做。

要获得单独的进程,对于 Linux,您需要 fork(),对于 Windows,您需要 CreateProcess()。最好的方法通常是制作一个函数来封装它。

bool RunProces(const std::string &sCmdLine)
{
    #if defined(WIN32)
        // launch with CreateProcess() ...
    #else
        // launch with fork() ...
    #endif
    return bSuccess;
}

但是,如果您只能使用线程,则可以使用可移植的 std::thread 类。

另一种方法是使用popen()(Windows 为_popen())。这将启动一个新进程并将其输出 (stdout) 重定向到管道。然后,您可以读取管道以检索子流程输出。

关于popen()的几点说明:

  1. 重定向标准输出会使子流程与用户交互变得不切实际。
  2. 设置管道会产生一些开销。除非您产生大量子流程,否则可能并不重要。
  3. 我从未见过popen() 用于启动非控制台Windows 程序(没有main() 功能)。如果这样做有问题,我不会感到惊讶。

【讨论】:

  • 与此处提出的 popen/_popen() 相比,create process/fork 有什么优势吗?:groups.google.com/forum/#!topic/wx-users/KadLJ-g4sEU
  • 取决于你想要什么。 popen() 将其输出写入管道,然后您可以读回该管道。如果这是可取的,那么使用 popen()。如果子程序需要与用户交互,我可能不推荐popen()。除此之外,两者可能都可以正常工作。你可能会争辩说你不想要管道输出,然后避免设置管道的开销——但开销不会很大。
  • 不需要与用户进行任何交互。一旦你添加这个而不删除当前的,我会接受你的回答:) 所以在 Windows 中它是一样的(MinGW 和 MSVC)?
【解决方案2】:

您将不得不将相当多部分代码从辅助线程移动到主线程。您所指的wxWidgets documentation 说明了一切:

当一个 wxProcess 对象被传递给 wxExecute() 时,它的 OnTerminate() 进程终止时调用虚方法。这允许 要(异步)通知进程终止的程序 并检索其退出状态,这是不可用的 wxExecute() 在异步执行的情况下。

以下:

目前 wxExecute() 只能从主线程使用,调用 来自另一个线程的这个函数将导致断言失败 调试构建,但无法正常工作。

因此,您需要消除从辅助线程调用wxExecute 的需要。您应该如何执行此操作取决于您的应用程序,但它可能涉及辅助线程使用wxQueueEvent 向主线程发送自定义 wxWidgets 事件。然后主线程通过在异步模式下调用wxExecute 来处理该事件稍后检索其结果。

现在如何处理结果?

理想情况下,您可以重新编写应用程序逻辑,以便辅助线程不需要结果,而是:

  1. 主线程自己处理,-或-
  2. 另一个辅助线程被启动并处理它。

这将最大限度地减少您必须执行的同步量,从而减少难以发现的并发编程错误的可能性。

【讨论】:

  • 将 wxExecute 移动到主线程会冻结我的 gui,因为该操作需要很长时间才能执行,并且必须是同步的。
  • 我不明白...为什么不能用 wxEXEC_ASYNC 调用 wxExecute?
  • 它有什么不同?
  • 它会使调用异步。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2011-09-16
相关资源
最近更新 更多