Run and break an infinite loop using two threads

2019-02-11 09:23发布

问题:

I am trying to run a loop until the user chooses to break out of it. Whether the user wants to run the function all night or for just a few seconds the loop should repeat until the user decides to stop it.

In researching solutions I came across using two threads to achieve this. The first thread would run the infinite loop while the second thread waited for user input. Upon receiving that input the second thread would terminate the first and then return.

  • How do I use the second thread to terminate the first?

#include <iostream>
#include <iomanip>
#include <ctime>
#include <thread>
#include <cstdlib>
#include <Windows.h>

using namespace std;

void timeCount()
{
    time_t rawTime;
    struct tm * timeinfo;

    do
    {
        Sleep(500);
        system("cls");
        time(&rawTime);
        cout << "Seconds passed this epoch:" << rawTime << endl << endl;
        timeinfo = localtime(&rawTime);
        cout << "The local time is:" << asctime(timeinfo) << endl;
        timeinfo = gmtime(&rawTime);
        cout << "The UTC time is :" << asctime(timeinfo) << endl;
    } while (1 != 0);

};

void getStop()
{
    system("pause");
};

void timeSince()
{
    thread counter(timeCount);
    thread stopper(getStop);
    counter.detach();
    stopper.join();

    counter.~thread();
};

回答1:

I usually use an atomic<int> or atomic<bool> to do it.


Thread function

void run( atomic<bool> & quit ) {
   while (!quit) {
      // Do some work.
   }
}

Mainthread:

int main() {
   // Just to show you can do this with more than 1 extra thread.
   unsigned int nThreads = std::thread::hardware_concurrency(); 

   std::atomic<bool> loopFlags[nThreads];
   std::thread       threads[nThreads];

   // Start threads
   for ( int i = 0; i < nThreads; i++) {
       loopFlags[i] = false;
       threads[i]   = std::thread(run, std::ref(loopFlags[i]));
   }

   usleep(10000); // Sleep for a while or do something else.

   // Shutdown other threads
   for ( auto & flag : loopFlags ) {
       flag = true;
   }

   // Wait for threads to actually finish.
   for ( auto& thread : threads ) {
       thread.join();
   }
   // Resume what you were doing.
}