4

So I've been making a terminal-based quiz as my first-year project, I decided to display a timer along with the code, but the timer doesn't let the program proceed cause of the infinite loop used in the timer.

How do I proceed through this problem?

    void timer()
{
    while (true) {
        clock_display();//Function loaded with manipulators to just show the 00:00:00 interface 
        sleep(1);
        sec++;
        if (sec == 60) {
            mins++;
            if (mins == 60) {
                hrs++;
                mins = 0;
            }
            sec = 0;
        }
    }
}

int main(){
     timer();
     //Other code I have to run
}
Uwe Keim
  • 39,551
  • 56
  • 175
  • 291
Subjugator
  • 43
  • 4

1 Answers1

4

This problem is more difficult as it might seem. You want the same program to do 2 things at the same time. While this is a common scenario these days and most programs run just this way, this is not the level expected from first-year students.

What you need is concurrent programming, supposed to be a hard stuff.

So here's the simplest example of the solution to you problem I could think of. However, concurrency is difficult: you need to take a special course to understand what and why is going on here.

#include <iostream>
#include <thread>
#include <cmath>

void timer()
{
    int sec = 0;
    while (true)
    {
#pragma omp critical
        std::cout << sec++ << "\n";

        std::this_thread::sleep_for(std::chrono::duration<double>(1.0));
    }
}

void my_stuff()
{
    for (int i = 0; i < 100; i++)
    {
        double x = 0.0;
        for (int j = 0; j < 10'000'000; j++)
        {
            x += sin(i + j);
        }
#pragma omp critical
        std::cout << "x = " << x << "\n";
    }
}

int main()
{
#pragma omp parallel
#pragma omp sections
    {
#pragma omp section
        timer();
#pragma omp section
        my_stuff();
    }
}

Compile it as a C++ program that uses OpenMP: this is the simplest library for concurrency. Under Linux: add -fopenmp to the compiler flags, for other OSs the Internet is full of answers.

  • I use #include<thread> only to be able to run sleep_for to put the program to sleep. This is a portable way, but you can use other methods. Generally, #include<thread> is the C++ way to concurrency, but I believe this might be too difficult for you.
  • Then you have all these #pragmas. This is not a place for an OpenMP tutorial, find them yourself, there're plenty of them.
  • critical pragma introduces a critical section to protect resources (here: std::cout) shared by competing threads. Go find a tutorial about it.
  • The (two) threads are automatically spawn in sections pragma, if only the program has been compiled properly and is run on a processor with at least 2 cores (physical or virtual).
  • The threads to be run are identified by the section pragma

That's it. I hope it'll work for you.

As soon as it works, find a good tutorial/textbook on OpenMP and/or C++11 concurrency model.

zkoza
  • 2,644
  • 3
  • 16
  • 24
  • Sorry I didn't really get the code, but if I put my int main() excluding timer() in my_stuff(), then this should work? – Subjugator Jul 23 '21 at 08:57
  • 1
    Yes. The only problem is with `std::cout`: you need to protect each line containing it with `#pragma omp critical`. This is inconvenient, so you'd better wrap `std::cout` in a class or function and protect it there. If you won't, the program will run except the display, which will *sometimes* be a bit chaotic. – zkoza Jul 23 '21 at 09:10
  • 1
    You can think that `timer` and `my_stuff` are 2 kinda independent programs (processes) that, unlike really independent programs, share some resources: global memory (including `std::cout`), opened files, heap-allocated memory ('operator new`) etc. All local variables are "private", so no need to worry about them. Because they share resources, they are not regular "processes", but a bit lighter "threads". Access to shared resources requires some synchronization. And this requires taking a course / tutorial on concurrent programming. OpenMP automatizes most of these tasks, but not all. – zkoza Jul 23 '21 at 11:20