保持 boost.process 在函数之外处于活动状态,该函数被调用

Keep boost.process alive outside of the function is was called from

本文关键字:函数 活动状态 调用 process boost 保持      更新时间:2023-10-16

我在Windows 10上使用Visual Studio 2019,使用boost.process库。我正在尝试制作国际象棋,并且我正在使用 Stockfish 引擎作为单独的可执行文件。我需要引擎贯穿整个游戏,因为这就是它的设计使用方式。

目前我在ChessGame.h

class ChessGame 
{
public:
void startStockFish();
void beginGame();
void parseCommand(std::string cmd);
private:
boost::process::child c;
boost::process::ipstream input;
boost::process::opstream output;
}

在国际象棋游戏中.cpp

#include ChessGame.h
void ChessGame::startStockFish()
{
std::string exec = "stockfish_10_x32.exe";
std::vector<std::string> args = { };
boost::process::child c(exec, args, boost::process::std_out > input, 
boost::process::std_in < output);
//c.wait()
}
void ChessGame::beginGame()
{
parseCommand("uci");
parseCommand("ucinewgame");
parseCommand("position startpos");
parseCommand("go");
}
void ChessGame::parseCommand(std::string cmd)
{
output << cmd << std::endl;
std::string line;
while (std::getline(input, line) && !line.empty())
{
std::cout << line << std::endl;
}
}

而且主要是.cpp

ChessGame chessGame = ChessGame(isWhite); //isWhite is a boolean that control who the player is, irrelevent to the question
//std::thread t(&ChessGame::startStockFish, chessGame);
chessGame.startStockFish();
chessGame.beginGame();

问题是我相信一旦函数 startStockFish 完成它就会终止 c,因为如上所述没有输出到终端,但是如果我在 startStockFish() 中使用 beginGame(),它会按预期输出。此外,如果我取消注释 c.wait() 行并且功能等待鳕鱼干退出,它就会卡住,因为鳕鱼干永远不会收到退出命令。如果我尝试在 main 中的单独线程上运行 startStockFish(如上所示),我会 收到以下两个错误:

功能测试宏的参数必须是简单的标识符。
在文件 'boost\system\detail\config.hpp' 行 51 中

'std::tuple::tuple':没有重载函数需要 2 个参数。
在文件"内存"行 2042 中

另外,我不想使用线程,因为我可以想象它会在输入和输出流方面存在自己的问题。

那么有没有办法让我在这个函数之外保持进程的活动,或者我需要以其他方式重新组织我的代码?我相信在 main 中调用进程会起作用,但我真的不想这样做,因为我想将所有与国际象棋相关的代码保留在 ChessGame.cpp 中。

好的,我相信在初始化startStockFish()的 boost.process 子项后添加c.detach();已经完成了我想要的,因为程序不再c函数结束时终止。输入似乎在分离的过程中工作正常,只需编写output << cmd << std::endl;其中cmd是所需的命令,因为std::string没有问题。但是,输出确实存在一些问题,通常的方法是

std::string line;
while (std::getline(input, line) && !line.empty())
{
// Do something with line
}

有些工作,但是当没有更多的行要输出时,std::getline(input, line)会陷入无限循环。我找不到直接的解决方案,但我确实找到了解决方法。

首先,我将 boost.process 子项的初始化更改为

boost::process::child c(exec, args, boost::process::std_out > "console.txt", boost::process::std_in < output);

然后将输入更改为std::ifstream,文件读取器流。然后得到我使用的输出

input.open("console.txt");
std::string line;
while (std::getline(input, line))
{
// Do something with line
}
input.close();

我还在startStockFish()的开头添加了remove("console.txt");,以获得新的文本文件。

我不相信这是最好的解决方案,因为我担心如果 stockfish 尝试写入控制台会发生什么.txt因为输入是从中读取的,但这似乎没有发生,或者如果它发生了,似乎不是问题,所以现在它是一个足够的解决方案。