循环得到cin输入

时间:2016-12-18 17:10:22

标签: c++ multithreading

是否可以创建一个while循环,如:

function customizeHeader() {
  var window_top = $(window).scrollTop();
  if ($('.header-wrapper').hasClass('stuck')) {
    $('#masthead').removeClass('nav-dark');
  } else {
    $('#masthead').addClass('nav-dark');
  }
}

$(function() {
  $(window).scroll(customizeHeader);
  customizeHeader();
});

这样可以保持循环并获取用户输入控制台的内容而不会像执行bool stop_input = false; while (!stop_input) { // Keep getting inputed string // Maybe like std::getline(std::cin, str_input); } std::cin那样停止(冻结)。

我感兴趣的是有一个单独的线程,在等待用户输入内容时会执行其他操作并按Enter键,然后std::getline()将成立,用户输入将被禁用。

这可能吗?怎么样?

编辑:

例如,如果我这样做:

stop_input

如果我创建了一个像上面这样的函数,编译它并启动了一个调试器,那么第二次调用std :: getline()时调试器(程序)就会停止。我不希望这种情况发生,我希望通过设置void test() { std::string str; while (!stop_input) { std::getline(std::cin, str); } }

让这个循环连续运行直至停止

EDIT2:

主线程:

stop_input = true;

阅读帖子:

void someFunction()
{
    string read_input;
    thread get_input = thread(readInput, &read_input);

    while(1) {
        if (buttonPressed(ENTER) {
            stop_input = true;
            get_input.join();

            // Do something with 'read_input' string.
        } else if (buttonPressed(ESC) {
           stop_input = true;
           get_input.join()

           // Discard 'read_input' string and return from this function.
           break;
        }
    }
}

P.S。 Ofcourse主线程也会做一些工作,与输入读取无关。

4 个答案:

答案 0 :(得分:0)

我不确定我的问题是否正确,但如果您只想在线程中运行某些内容并允许输入直到线程中的任务完成,那么我就是这样做的:

std::vector< int > v;
std::atomic< bool > stop_input( false );
std::thread t( [ &v, &stop_input ]() 
{
  for( int i = 0; 1'000'000'000 > i; ++i ) v.push_back( i );
  stop_input = true;
} );
std::string m;
while( !stop_input )
{
  std::cin >> m;
  std::cout << "Your message: " << m << std::endl;
}
t.join();

但是,这只会在线程中任务终止后的用户输入后终止。它不会“中断”std::cin

答案 1 :(得分:0)

你是说你有两个线程,一个等待用户输入然后唤醒另一个线程?

你创建一个负责循环的线程,然后你的另一个线程接受用户输入并设置bool。循环线程不断调用另一个线程来查看是否有用户输入..

像这样:

#include <iostream>
#include <thread>
#include <chrono>

using namespace std;

string s;
bool b = false;

void doStuff()
{
    int i = 0;
    while (!b)
    {
        cout << i << ' ';
        ++i;
        this_thread::yield();
        //this_thread::sleep_for(chrono::seconds(1));
    }
    cout << "you wrote: " << s << endl;
}

int main()
{
    thread t(doStuff);
    char c;
    while ((c = cin.get()) != '\n')
        s += c;
    b = true;
    t.join();
}

Sleep和yield会自动阻止该线程并调用另一个可用的线程。 get()也自动阻塞它的线程。如果你想要非阻塞的东西,那么这可能与操作系统有关......

编辑:

您可以分离线程以使其独立执行,然后在访问它们之前锁定共享资源。

#include <iostream>
#include <thread>
#include <mutex>

using namespace std;

mutex m;
string s;
bool stopInput = false;

char c = 0;

void readInput()
{
    while (!stopInput)
    {
        m.lock();
        c = cin.get();
        s += c;
        m.unlock();
    }
}

int main()
{
    thread t(readInput);
    t.detach();

    while (true)
    {
        m.lock();
        if (isEnter(c))
        {
            stopInput = true;
            cout << "Input: " << s << endl;
            break;
        }
        else if (isEscape(c))
        {
            stopInput = true;
            break;
        }
        m.unlock();
    }
}

答案 2 :(得分:0)

这个问题似乎与线程同步有关。

假设stop_input本身已正确同步,例如由于它是一个atomic_bool,当检查后stop_input立即设置为true时,仍然不会阻止你的线程在while循环体内做它的东西。

您想要实现的是什么?知道这一点,我们可以帮助您找到适合您特定问题的线程安全和线程感知解决方案:)

答案 3 :(得分:0)

可以让getline(或cin.getcin.peek等在一个单独的线程中与&#34;退出&#34; -variable一起运行喜欢&#34; stop_input&#34; (见下面的例子)。

请注意,设置stop_input=true一旦被调用,显然不会中断getline(或cin.getcin.peek,...)。请注意,在循环中,如while (!stop_input) { std::getline(std::cin, str); ... },主线程不太可能在重新进入循环之前设置stop_input=true。因此,在用户输入值后,主线程可能无法立即停止输入;在循环可以对getline的任何更改做出反应之前,将再次输入stop_input

还应该注意其他线程也不会使用getline,因为 - 至少据我所知 - 它不是线程安全的。

#include <iostream>
#include <queue>
#include <thread>
#include <mutex>

bool stop_input = false;
std::queue<std::string> commandQueue;
std::mutex commandQueueMutex;

void getLineUntilInputStopped()
{
    std::string str;
    while (!stop_input) {
        std::getline(std::cin, str);
        if (str == "stopinput")
            stop_input = true;

        commandQueueMutex.lock();
        commandQueue.push(str);
        commandQueueMutex.unlock();
    }
    std::cout << "Listening on input stopped.";
}


int main(int argc, const char * argv[]) {

    std::thread t(getLineUntilInputStopped);
    t.detach();

    bool exit = false;
    while (!exit)
    {
        std::string command = "";
        commandQueueMutex.lock();
        if (commandQueue.size() > 0)
        {
            command = commandQueue.front();
            commandQueue.pop();
        }
        commandQueueMutex.unlock();

        if (command.size() > 0)
        {
            if (command == "exit")
            {
                exit = true;
                std::cout << "exit program.";
            }
            else
            {
                std::cout << "command '" << command << "' entered.";
            }
        }
        else
        {
            std::cout << "in the meanwhile do something else\n";
            std::this_thread::sleep_for (std::chrono::seconds(3));
        }
    }

    return 0;
}