c++ - piping stockfish 在 fedora 中行为不端

标签 c++ pipe virtual-machine fedora

在我项目的某个地方,我使用 fork 和 pipe 来执行另一个进程并通过管道传输它的 I/O 以与其通信(我用 C++ 编写它)。当我在 Ubuntu 14.04 中编译它时没有问题,它会工作得很好,但是我在 WMWare 虚拟机上的 fedora 中编译它并且奇怪的事情开始发生。如果我在终端中运行二进制文件,没有错误,但管道中不会写入任何内容(但获取字符流会起作用)。我试图在 fedora 中调试我的代码,我在我的代码中放置了一个断点,但是当进程试图从管道读取时给出了一个损坏的管道信号(在终端中执行时没有信号)。 那么,你们以前遇到过这样的问题吗? debian 和 red hat linux 之间的管道有什么区别吗?还是因为我在虚拟机上运行 fedora?

代码:

int mFD_p2c [2];
int mFD_c2p [2];
int mEnginePID;

if (pipe(mFD_p2c) != 0 || pipe(mFD_c2p) != 0)
{
  cout << "Failed to pipe";
  exit(1);
}
mEnginePID = fork();

if (mEnginePID < 0)
{
  cout << "Fork failed";
  exit(-1);
}
else if (mEnginePID == 0)
{
  if (dup2(mFD_p2c[0], 0) != 0 ||
      close(mFD_p2c[0]) != 0 ||
      close(mFD_p2c[1]) != 0)
  {
     cout << "Child: failed to set up standard input";
     exit(1);
  }
  if (dup2(mFD_c2p[1], 1) != 1 ||
      close(mFD_c2p[1]) != 0 ||
      close(mFD_c2p[0]) != 0)
  {
     cout << "Child: failed to set up standard output";
     exit(1);
  }

  string engine = "stockfish";
  execlp(engine.c_str(), (char *) 0);
  cout << "Failed to execute " << engine;
  exit(1);
}
else
{
  close(mFD_p2c[0]);
  close(mFD_c2p[1]);

  string str = "uci";
  int nbytes = str.length();
  if (write(mFD_p2c[1], str.c_str(), nbytes) != nbytes)
  {
     cout << "Parent: short write to child";
     exit(1);
  }

  cout << "The following string has been written to engine:\n"
       << string(1, '\t') << str;

  char readBuffer[2];
  string output = "";

  while (1)
  {
     int bytes_read = read(mFD_c2p[0], readBuffer, sizeof(char));

     if (readBuffer[0] == '\n')
        break;

     readBuffer[bytes_read] = '\0';

     output += readBuffer;
  }

  cout << "Got: " << output;
}

最佳答案

我看到您正在使用 Stockfish。我也确实经历过 Stockfish 的这种行为。问题在于它如何处理输出。在misc.h中定义:

#define sync_cout std::cout << IO_LOCK

再次查看代码,我们将看到 IO_LOCK 是一个枚举,用于 cout 的重载友元运算符:

std::ostream& operator<<(std::ostream& os, SyncCout sc) {

  static Mutex m;

  if (sc == IO_LOCK)
      m.lock();

  if (sc == IO_UNLOCK)
      m.unlock();

  return os;
}

我在这里看到的是,在使用 cout 期间,互斥体被锁定。我不知道这究竟如何影响 cout 在管道而不是 stdout 中的输出,但我肯定这是问题的原因。您可以通过删除锁定功能来检查它。

编辑:我忘了提到管道行为在基于 linux 的系统中并没有像前面提到的那样不同,但是在处理与管道一起使用的互斥量的发行版之间可能存在细微差别。

关于c++ - piping stockfish 在 fedora 中行为不端,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/30257108/

相关文章:

c++ - 在 C++ 中共享内存?

c++ - 如何在 C++ 中读取 Evolution 邮件管道?

c - 当不知道将通过管道发送多少数据时,如何从管道中读取数据?

python - 控制 Python 交互式 shell 的输入/输出

virtual-machine - 如何在不同端口上使用 Vagrant 专用网络访问 VM?

c++ - SHIMVIEW : shiminfo means? 是什么

c++ - 在 C++ 中模拟 C# 锁定语句

c++ - QVariant 到 QObject*

azure - 如何连接到Azure VM上的docker?

javascript - 处理网页上的所有/任何链接点击