我正在写一个国际象棋引擎,这是我想要实现UCI protocol的一个例子:
//search.h
#pragma once
#include<atomic>
static std::atomic_bool stop=false;
namespace Search
{
int Alphabeta()
{
int r = 10;
int Rounds = 0;
while ((++Rounds<20)&&!stop)
{
int sum = 0;
for (size_t i = 0; i < 100000000; i++)
{
sum += i;
}
sync_cout << sum<< sync_endl;
}
sync_cout << "Stopping" << sync_endl;
return r;
}
}
//UCI.h
#pragma once
#include<iostream>
#include<string>
#include <sstream>
#include<thread>
#include<mutex>
#include<condition_variable>
enum SyncCout { IO_LOCK, IO_UNLOCK };
//taken from StockFish
std::ostream& operator<<(std::ostream& os, SyncCout sc) {
static std::mutex m;
if (sc == IO_LOCK) m.lock();
if (sc == IO_UNLOCK) m.unlock();
return os;
}
#define sync_cout std::cout << IO_LOCK
#define sync_endl std::endl << IO_UNLOCK
#include"search.h"
class Thread
{
public:
Thread()
{
nativeThread = std::thread(&Thread::MainLoop, this);
sync_cout << "@Constructor" << sync_endl;
}
void MainLoop()
{
while (!exit)
{
while (pause)
{
sync_cout << "@Waiting" << sync_endl;
std::unique_lock<std::mutex> lk(mutex);
cv.wait(lk);
lk.unlock();
}
sync_cout << "@UCILoop" << sync_endl;
std::string token, cmd;
while (!pause && !exit && std::getline(std::cin, cmd))
{
sync_cout << "@Processing" << sync_endl;
std::istringstream is(cmd);
is >> std::skipws >> token;
if (token == "stop")
{
stop = true;
PauseThread();
}
else if (token == "isready") std::cout << "readyok" << std::endl;
else if (token == "pause") PauseThread();
}
}
}
void PauseThread()
{
//pause
std::lock_guard<std::mutex> lk(mutex);
pause = true;
}
void ResumeThread()
{
std::lock_guard<std::mutex> lk(mutex);
pause = false;
cv.notify_one();
}
~Thread()
{
sync_cout << "@Destructor" << sync_endl;
mutex.lock();
pause = false;
exit = true;
cv.notify_one();
mutex.unlock();
nativeThread.join();
}
private:
std::thread nativeThread;
std::mutex mutex;
std::condition_variable cv;
bool pause = true, exit = false;
};
namespace UCI
{
void Loop()
{
Thread th;
std::cout << "@PrimaryLoop : "<<std::endl;
std::string token, cmd;
while (std::getline(std::cin, cmd))
{
std::cout << "Processing : ";
std::istringstream is(cmd);
is >> std::skipws >> token;
if (token == "go")
{
std::cout << "go ok" << std::endl;
stop = false;
th.ResumeThread();
Search::Alphabeta();
th.PauseThread();
}
else if (token == "isready") std::cout << "readyok" << std::endl;
else if (token == "quiet")
{
std::cout << "quieting" << std::endl;
break;
}
}
}
}
和主要:
#include"UCI.h"
int main()
{
UCI::Loop();
}
一切正常,唯一的例外是搜索正常完成而没有收到UCI命令&#34;停止&#34; ,所以搜索将在辅助UCI线程等待输入时返回@&#34; std :: getline&#34; ,我打算写一下stdin流&#34;暂停&#34;从代码中可以看出,在知道这是最好的非便携式&amp;错了,我有什么选择,还是有其他方法可以暂停一个帖子而不管它当前正在执行什么?