【问题标题】:STDIN seems to be broken after call to "system" invoking mpiexec在调用“系统”调用 mpiexec 后,STDIN 似乎被破坏了
【发布时间】:2012-12-19 12:14:30
【问题描述】:

这是我第一次在这里发帖,所以请原谅任何格式问题。

我有一个交互式程序,它产生外部进程并监控它们的 IO。一切正常,直到我用“mpiexec”生成了一些东西,之后 STDIN 似乎中断了。

我知道这对于大多数人来说很难重现,但如果有人看到任何明显的或知道这个问题....请帮忙!

这是一个sn-p:

int main( ... )
{
  std::string choice;
  while(std::getline(std::cin,choice)){
     if(!choice.empty()){
       if(choice == "Parallel"){
        system("mpiexec ./aprogram");
       }
       if(choice == "Serial"){
        system("./aprogram");
       }
       // Now the external process is done... so far, so good
       std::cout << "Program is done. Press ENTER to continue." 
                 << std::endl;
       // This next line *works* if the external process was serial
       // But *fails* when "mpiexec" was invoked 
       std::getline(std::cin,choice);
       if(std::cin.eof()){
         std::cout << "STDIN has been closed." << std::endl;
         exit(1);
       }
     }
  }
} 

我已经尝试了 很多 各种东西,例如管道,显式分叉,细致的描述符管理。最奇怪的是,如果我关闭并保存标准输入,然后在“mpiexec”返回后恢复它,那么我不再在 std::cin 上获得 EOF,而是 std::getline(std::cin,... ) 不再阻塞!程序进入一个无限循环,在 std::readline 调用中从 std::cin 读取零字节。

如果,当外部进程在 mpiexec 下运行时,我将一堆数据堆叠到 std::cin 中(例如通过键入),然后对 std::readline 的后续调用正确解析我卡在的数据行在那里,但又一次......一旦完成读取该数据,它就会继续进行无限循环(即即使没有数据要读取,也不会阻塞 std::readline(std::cin,..) !呃。真烦人。

非常感谢任何帮助。

干杯!

【问题讨论】:

  • 您在哪个平台上使用哪种 MPI 实现?
  • 我们目前在几个不同的基于 Linux 的平台(其中大多数是基于 SL 或 CentOS )。我没有尝试过使用 OpenMPI,但是这个集成系统中的一些应用程序不能很好地使用 OpenMPI。我相信问题必须集中在“mpiexec”对 STDIN 所做的事情上。我将尝试获得更好的 sn-p,以便可以使用 vanilla mpich 轻松复制它。
  • 我可以用您的示例代码和 MPICH-3.0.1 重现您的问题。我正在调查。
  • 优秀。非常感谢,戴夫。
  • 尚无修复,但它似乎并没有真正关闭底层文件描述符。相反,对 fd 0read 调用返回了 EAGAIN,就好像标准输入已被设为非阻塞一样。我还没有找到我们正在这样做的任何地方,但这里肯定发生了一些有趣的事情。我们会继续关注它。

标签: system stdin readline fork mpiexec


【解决方案1】:

我想我解决了你的问题,对我来说,对 Serial 或 Parallel 的调用被阻止,我认为这是 std::cin.eof() 测试,

  std::getline(std::cin,choice);
  if(std::cin.eof()){         
     td::cout << "STDIN has been closed." << std::endl;
     exit(1);
   }

但是,将其更改为 std::cin.get(),对并行运行和串行运行都非常有效。

   if(std::cin.get()) {
     std::cout << "STDIN has been closed." << std::endl;
     exit(1);
   }

在我的系统上工作。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2020-04-08
    • 2020-02-22
    • 2019-08-07
    • 2021-09-22
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多