Thread (sleep) one second then calls the method to update it by a second

I have a 12 hour clock and a 24 hour clock. I need to have a thread that sleeps one second then calls the method to update by a second. I first tried the getc and unget c functions but have been told that I need to thread sleep for one second and then call method to update it by a second. Below is the snippet of code. Everytime I give user input to add an hour, or minute, and seconds to the clocks it also adds a second to the clocks at the same time. I don't think this is what is supposed to be happening. Any suggestions on how I can accomplish this task is appreciated. I have many tabs open adn the more I research the more confused I seem to get.



1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23

#include <chorno> 
#include <threa>
#include <iostream>


 int selection;

        using namespace std::this_thread;     // sleep_for, sleep_until
        using namespace std::chrono_literals; // ns, us, ms, s, h, etc.
        using std::chrono::system_clock;

        sleep_for(10ns);

        
        sleep_until(system_clock::now() + 1s);

        time_12Hr_Clock.addOneSecond(); 

        time_24Hr_Clock.addOneSecond();

        
        cin >> selection;  
I don't understand what you're asking. Your program is adding to the time every second. And a user can also choose to update the time with their input?

But when the user types in input, you don't want it to add a second as usual? Or do you mean that user input TRIGGERS the addition of a second to time, even when it shouldn't?

Here's a small example that may help you:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
#include <chrono> 
#include <thread>
#include <iostream>
#include <ctime>
#include <atomic>

using namespace std;

//Making some random time for simplicity
atomic<int> hours = 11, minutes = 6, seconds = 24;

//Adds a second to the time every second
void track()
{
	while (true)
	{
		this_thread::sleep_for(1000ms);

		seconds++;

		if (seconds == 60)
		{
			seconds = 0;
			minutes++;
		}
		if (minutes == 60)
		{
			minutes = 0;
			hours++;
		}
		if (hours == 24)
		{
			hours = 0;
		}
	}
}

//Adds user input time to the overall time
void add(int time)
{
	seconds += time;

	while(seconds >= 60)
	{
		seconds = seconds - 60;
		minutes++;
	}
	while (minutes >= 60)
	{
		minutes = minutes - 60;
		hours++;
	}
	while (hours >= 24)
	{
		hours = hours - 24;
	}

}

int main()
{
	thread t1(track); //start thread to add +1 every second

        //get user input to add to time
	while (true)
	{
		cout << hours << ':' << minutes << ':' << seconds << "\n\n";
		int time;

		cout << "Enter Time To add In Seconds: ";
		cin >> time;

		add(time);

		cout << '\n';

		if (time < 0)
			continue;
	}
}
Last edited on
std::this_thread::sleep_for is completely unsuitable as a timer.
See cppreference:
Blocks the execution of the current thread for at least the specified sleep_duration.

This function may block for longer than sleep_duration due to scheduling or resource contention delays.

The standard recommends that a steady clock is used to measure the duration. If an implementation uses a system clock instead, the wait time may also be sensitive to clock adjustments.

https://en.cppreference.com/w/cpp/thread/sleep_for

Also, Microsoft's standard library uses a system clock. Therefore under this implementation sleep_for is de facto broken; any sleeping thread may hang for an arbitrary amount of time if the system clock is adjusted.
https://developercommunity.visualstudio.com/t/bogus-stdthis-threadsleep-for-implementation/58530

Note "Fixed pending release" is somewhat misleading because the fix would affect the Standard library's binary interface and therefore will not be released until a sane decision about binary compatibility is reached.
Last edited on
1
2
3
4
5
while(seconds >= 60)
	{
		seconds = seconds - 60;
		minutes++;
	}


That's not how it would usually be coded. Use mod and int division:

1
2
minutes += seconds / 60;
seconds %= 60;

As mbozzi says above, sleep_for() will suspend execution of the thread for at least the specified duration. In practice, the suspension time could be longer - possibly much longer - depending upon other executing threads, priorities etc.

Windows, Linus etc are not real-time OS's so any timing is only approx.

Often if a suspension delay is appropriate (as opposed to using synchronization) then the exact actual suspension time isn't critical. However, when you want to update say a clock then it might well be. The longer the suspension, the more likely the exact suspension time is more than that specified. After some hours you could easily be a few seconds adrift.

In cases like this, I suggest that one approach is to obtain the new system time after execution has resumed.

As Pseudo:

1
2
Sleep(1s);
Obtain current time;


Another approach is (as pseudo):

1
2
3
4
5
Obtain the current time (t1); 
Repeat {
    Sleep(0); //which causes the thread to relinquish the remainder of its time slice to any other thread that is ready to run
    Obtain the current time (t2);
} Until t2 - t1 is that required.

Last edited on
That's not how it would usually be coded. Use mod and int division

That is the best way, I put that in only for completeness - I had some code and I just switched out the "if"s to "while". int main() is what I believe is the relevant code that would help them.

They seem to not have differentiated between adding a second to the timer and adding the user input to the timer.
Topic archived. No new replies allowed.