【问题标题】:How to create a single process but multithreads MFC GUI application with MPI?如何使用 MPI 创建单进程但多线程的 MFC GUI 应用程序?
【发布时间】:2015-08-20 14:40:53
【问题描述】:

我只需要使用 MSMPI 编写一个简单的 MFC Windows 应用程序,但我不想启动多个进程,因为我的 GUI 应用程序可能需要在多线程部分之前进行一些用户交互。例如,我想在单击“运行”按钮后创建 2 个线程。

我尝试使用命令行运行我的程序:mpiexec.exe -n 2 myprogram.exe,但这会创建两个进程,我会看到两个应用程序窗口。

我也尝试过 Visual Studio 2010 中的 MPI 集群调试选项,但它也会创建两个进程。

这似乎是一个非常基本的问题,但我发现在 Google 中很难找到答案。

编辑

为了消除这里的混乱,我必须澄清一些事情:

  1. 我有一个非常复杂且庞大的代码库,已经使用 MS-MPI 实现并行性,我必须在它之上构建一个 MFC GUI。出于这个原因,我不能使用任何其他并行机制,例如 std::thread,因为这意味着我必须重写很多负担不起的东西。
  2. 据我了解,要启动 MPI 程序,我必须在 Windows 中运行名为 mpiexec.exe 的外部程序。我还没有弄清楚是否可以自行启动该程序并仍然实现 MPI 功能。我对 MPI 很陌生。我不太确定是否有可能实现我的要求。如果不是,如果有人能告诉我原因和可能的解决方法,我将不胜感激。

简单地说,我想为支持 MPI 的软件创建一个 MFC GUI 包装器,这必须是一个多线程程序,而不是这个 GUI 包装程序的多个实例(进程)(例如,通过 mpiexec -n 2 xxx 运行这个程序.exe 只会创建同一程序的 2 个实例)

【问题讨论】:

  • 为什么坚持使用MPI?你探索过 std::thread 吗?
  • 如果现有代码库没有使用 MPI 实现,我不会坚持使用 MPI。现在我需要为这段代码构建一个 GUI,这就是我在这里结束的原因 - 我的问题中的描述只是一个简化的场景。
  • 那么,MPI 中的现有代码库是什么?如果不是,那么我建议使用 std::thread 除非你有特定的理由使用 MPI
  • 是的,现有的代码库在 MPI 中。所以我别无选择。
  • 我在上面的评论中说过,我的问题的描述只是一个简化的场景 - 其他人更容易理解我的问题。但实际的代码库比这复杂得多,我无法使用 std::thread 重写所有内容。

标签: c++ multithreading mfc mpi


【解决方案1】:

我猜您正在为您拥有的某些 MPI 软件创建某种图形前端。据我所知,您有两种选择。

选项 1

创建一个单独的 Win32 应用程序(不带 MPI)作为您的 GUI,让该应用程序运行“mpiexec”或具有正确参数的等效程序,以便在用户请求时启动应用程序。

选项 2

您需要确保仅在一个 MPI 实例上启动 GUI。您可以通过在启动期间从 MPI 中查找当前程序的 ID 来做到这一点,如果它是 0,则启动 GUI。

类似这样的:

int main(int argc, char** argv){
    int myid;
    ...
    MPI_Init(&argc, &argv);
    ...
    MPI_Comm_rank(MPI_COMM_WORLD,&myid);
    if(myid == 0){
        launchGui();
    }else{
        waitForAndProcessMessages();
    }
    ...
    MPI_Finalize();
    return 0;
}

显然,您仍然需要填写所有位以使 MPI 正常运行,但在此示例中,第一个启动的实例将成为 GUI 并且不进行任何处理。以后加入 HPC 的任何实例都将等待消息并处理它们,直到它们终止。

【讨论】:

  • 这正是我所要求的。这是否意味着在运行 MPI 应用程序时总会有多个进程而不是线程?
  • 是的,您可以在 HPC 集群中启动任意数量的进程,但只有第一个启动的进程才能获得 gui。
【解决方案2】:

我想在点击“运行”按钮后创建 2 个线程”

既然你有 VS 2010,我不确定 std::thread 的兼容性。您可以使用MFC's threading API 如下 -

CWinThread* myThread = AfxBeginThread(myThreadFunc, &threadInfoStruct);

您可以使用PostThreadMessage API 在各种 MFC 线程之间传递信息,即从 GUI 到业务逻辑,进而到 MPI 线程并返回。

当然,如果你的编译器支持std::thread,那是可行的方法。

与std::thread相关,通常实现你想要的最正确的方法是使用std::async。阅读Effective Modern C++中基于线程的编程与基于任务的编程。

【讨论】:

  • 谢谢,但我无法使用其他 API 或库来实现并行性,因为我在问题的 cmets 和编辑中已经解释过。 p.s.不过,我并没有否决您的回答。
  • 我以为你建议使用 MFC 线程或 std::thread 来重新实现我现有代码库的并行部分,这就是为什么我说这不是一个选项,因为它会涉及很多工作.现在我刚刚意识到/理解您实际上是在建议使用单独的线程来启动我的 MPI 软件。这类似于 Emily L 的答案中的选项 1。谢谢。
  • @newbie 尽量保持现代 C++11 风格。您稍后会感谢您的选择。
  • 但我不太确定如何在实践中实现这个想法。要使用 MS-MPI 运行 MPI 程序,我想我必须先使用 mpiexec.exe 来启动可执行文件,然后如果我传递像 -n 2 myprogram.exe 这样的参数,它只会创建整个程序的两个实例,并且在每个程序(进程)中,然后会创建一个GUI线程和一些业务逻辑线程,这并不是我真正想要的......我想我们的误解来自这里......
猜你喜欢
  • 1970-01-01
  • 2020-01-11
  • 2012-05-15
  • 1970-01-01
  • 1970-01-01
  • 2010-12-04
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多