保持boost.process活着的功能是从

时间:2019-07-17 07:57:30

标签: c++ boost

我正在使用boost.process库在Windows 10上使用Visual Studio 2019。我正在尝试下象棋,并且我将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;
}

在ChessGame.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;
    }
}

在main.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()行,并且该功能等待退出stockfish,那么它将陷入困境,因为stockfish永远不会收到exit命令。如果我改为尝试在main中的单独线程上运行startStockFish(如上所示), 出现以下两个错误:

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

'std :: tuple :: tuple':没有重载函数带有2个参数。
在文件“内存”第2042行

此外,我也不想使用线程,因为我可以想象这会在输入和输出流中产生自己的问题。

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

1 个答案:

答案 0 :(得分:0)

好吧,我相信在c.detach();中初始化boost.process子级后添加startStockFish()已经达到了我想要的效果,因为该函数结束时该程序不再终止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();

我还将remove("console.txt");添加到startStockFish()的开头以获取新的文本文件。

我不确定这是否是最好的解决方案,因为我担心如果Stockfish试图在读取输入的同时尝试写入console.txt,会发生什么,但这似乎没有发生或没有发生。如果发生的话,这似乎是一个问题,所以现在这是一个适当的解决方案。