暂停正在等待输入的线程?

时间:2017-06-11 03:39:36

标签: c++ multithreading c++11 stdin condition-variable

我正在写一个国际象棋引擎,这是我想要实现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;错了,我有什么选择,还是有其他方法可以暂停一个帖子而不管它当前正在执行什么?

0 个答案:

没有答案