C++ 使用线程停止操作

C++ 使用线程停止操作,c++,arrays,multithreading,c++11,c++14,C++,Arrays,Multithreading,C++11,C++14,我正在为游戏分类编写一个程序。在程序中有一个表格,当计时器线程在后台工作时,播放器输入单词。我希望,当时间结束时,玩家将不能再输入了,轮到他了 我怎样才能做到这一点 表和计时器: void timer() { cout << "You got 2 minutes to finish\n"; //Changing the duration of the timer is done by changing the value of 'i' in the "for" loop

我正在为游戏分类编写一个程序。在程序中有一个表格,当计时器线程在后台工作时,播放器输入单词。我希望,当时间结束时,玩家将不能再输入了,轮到他了

我怎样才能做到这一点

表和计时器:

void timer()
{
    cout << "You got 2 minutes to finish\n";    //Changing the duration of the timer is done by changing the value of 'i' in the "for" loop
    for (int i = 120; i > 0; i--)
    {
        sleep_for(1s);
    }
    cout << "DING DONG!!! DING DONG!!! Time's up!!!\n";
}

void table(int plr)
{
    string ctr[12] = { "A cuntry", "A city", "An animal", "A plant", "An object", "A name", "Food", "Drink", "A game", "A movie", "A book", "A famous person" };
    string lst[6][12];           //first dimantion: how many players. second dimantion: how many catagories, third dimantion(if added) will be the round
    cin.ignore();                  //To avoid the "getline" reading the last input
    for (int x = 0; x<plr; x++)       //the player changes only after the previus player finishes
    {
        std::thread t1(timer);       //gives time to write the words. Optimaly it would finish the round for player when time is up
        t1.detach();
        cout << "When the timer ends please enter '0' in the remaining catagories\n";
        for (int i = 0; i<12; i++)        //changing catagory
        {
            cout << ctr[i] << ": ";
            getline(cin, lst[x][i]);
        }
        system("cls");
        cout << "Next player\n";
    }
}
完整代码:

// A program to keep track of points and time and to give a random letter for the game scattergories
#include<iostream>
#include<ctime>
#include<string>
#include <chrono>
#include <thread>
using std::cout;
using std::cin;
using std::string;
using std::getline;
using namespace std::chrono_literals;
using std::this_thread::sleep_for;

void ltr()    //gives a random letter
{
    char letter;
    letter = rand() % 26 + 65;         //assigns a random letter in ascii code to a char (resulting in a random letter)
    cout << "The letter is " << letter << "\n";
}

void timer()
{
    cout << "You got 2 minutes to finish\n";    //Changing the duration of the timer is done by changing the value of 'i' in the "for" loop
    for (int i = 120; i > 0; i--)
    {
        sleep_for(1s);
    }
    cout << "DING DONG!!! DING DONG!!! Time's up!!!\n";
}

void table(int plr)
{
    string ctr[12] = { "A cuntry", "A city", "An animal", "A plant", "An object", "A name", "Food", "Drink", "A game", "A movie", "A book", "A famous person" };
    string lst[6][12];           //first dimantion: how many players. second dimantion: how many catagories, third dimantion(if added) will be the round
    cin.ignore();                  //To avoid the "getline" reading the last input
    for (int x = 0; x<plr; x++)       //the player changes only after the previus player finishes
    {
        std::thread t1(timer);       //gives time to write the words. Optimaly it would finish the round for player when time is up
        t1.detach();
        cout << "When the timer ends please enter '0' in the remaining catagories\n";
        for (int i = 0; i<12; i++)        //changing catagory
        {
            cout << ctr[i] << ": ";
            getline(cin, lst[x][i]);
        }
        system("cls");
        cout << "Next player\n";
    }
    for (int x = 0; x<plr; x++)                   //this part (the whole "for" loop) is for confirming evreything is writen down
    {
        cout << "Player number " << x + 1 << ": ";
        for (int i = 0; i<12; i++)
        {
            cout << lst[x][i] << "    ";
        }
        cout << "\n";
    }
    sleep_for(5s);
}

int points()        //points gained per round
{
    int a, b, c, sum;
    cout << "How many sections only you got?\n";          //worth 15 points
    cin >> a;
    cout << "How many words only you got?\n";       //worth 10 points
    cin >> b;
    cout << "How many words you and another person got?\n";    //worth 5 points
    cin >> c;
    sum = a * 15 + b * 10 + c * 5;
    return sum;           //Note: It doesn't matter how many sections there are.
}

int act()    //running the program
{
    int Players, Points[6];
    cout << "How many people are playing? (Up to six players)";
    cin >> Players;
    ltr();
    table(Players);
    //Points = points();
    cout << "You have earned " << Points << " this round\n\n";
    return 1;
}

int main()
{
    auto start = std::chrono::high_resolution_clock::now();
    srand(time(NULL));    //gives a differant pattern of letters every time
    int Points;
    Points = act();
    for (;;)          //inf loop
    {
        int ph;
        cout << "Press 1 to continue or anything else to stop\n";
        cin >> ph;
        if (ph == 1)
        {
            Points += act();    //keeping score of the rounds
        }
        else
        {
            auto end = std::chrono::high_resolution_clock::now();
            break;
        }
    }
    cout << "You have earned a total of " << Points << " great job!";
    sleep_for(5s);       //time to read the last text
    return 0;
}

/*
To do list:
-Make timer stop the table when time is up
-Check if words in the table (for differant players) are the same and give points accordingly
-Check if words are actual words (connect an online dictonary?)
-Make interface? (if possible and I have time to learn how)
-Comment rest of the code
*/
附笔 我想让这段代码保持可移植性,所以我会预先提出一些建议,让它保持这种方式。不过,如果有任何建议,我将不胜感激。 我使用的是Windows10,但我正在编写控制台应用程序,我可以访问c++11和c++14


不可移植的解决方案

bool getUserInput(string &result, Time deadline) // pick a timer, any timer
{
  while(deadline > Time::now()) // assuming your timer has a now function
  {
     if(kbhit()) // THIS IS NOT PORTABLE. On windows it's called _kbhit()
     {
       char key = getch(); //read the key (also non-portable) 
       if(key == '\n' or key == '\r')
       {
          return true;
       }
       else
       {
         string += key;
       }
     }
   }
   return false;
 } 

为什么使用线程会使事情变得非常复杂?正如艾伦·考克斯曾经说过的那样,计算机是一台状态机。线程是为那些不能编程状态机的人设计的。基本上,标准C++中没有什么可以让STD::GETLIN比它正常的返回早,也就是说,在它完成收集用户输入之前。我不认为C++标准库提供任何形式的非阻塞读。任何解决方案都可能是特定于平台的。@JesperJuhl您如何建议在玩家输入时运行计时器?@IgorTandetnik如果这是唯一的方法,那就这样吧。即使它不可移植,我怎么做呢?根据定义,特定于平台的解决方案将特定于您计划运行的平台。你可以添加一个睡眠或者至少是一个收益,以便更好地处理系统上的其他进程。