Sharing variable value between threads

I want one thread to be constantly updating a variable and have a second thread respond when the variable is a certain value. The second thread isn't responding.

One thread simulates a one-second click. The other thread is waiting for the third click. The clicking is happening, but the second thread doesn't seem to be detecting when the variable equals 3.

The way I understand it, condition_variable.wait() constantly checks for the condition to be true. Maybe I'm missing something about how that works.

Output:
1
2
3
4
5
6
click number 1
click number 2
click number 3
click number 4
click number 5
...


Any help gratefully appreciated.

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
#include <iostream>
#include <thread>
#include <mutex>

std::mutex m1;
std::condition_variable cv1;
int click_counter = 0;

void do_click()
{
    std::chrono::steady_clock::duration d = std::chrono::steady_clock::duration::zero(); 
    std::chrono::duration<int> one_second(1); 
    while (true)
    {
        std::chrono::steady_clock::time_point t1 = std::chrono::steady_clock::now();
        do
        {
            std::chrono::steady_clock::time_point t2 = std::chrono::steady_clock::now();
            d = t2 - t1;
        } while (d < one_second);
        ++click_counter;
        std::cout << "click number " << click_counter << '\n';
    }
}

void click_listener()
{
    std::unique_lock<std::mutex> lock(m1);
    cv1.wait(lock, []() { 
        return click_counter == 3;
        });
    std::cout << "click_counter reached 3" << std::endl;
}

int main()
{
    std::thread met(do_click); 
    std::thread listen(click_listener);

    met.join();
    listen.join();

    return 0;
}
Last edited on
Study the example here:
https://en.cppreference.com/w/cpp/thread/condition_variable

You're missing cv1.notify_one();
the second thread doesn't seem to be detecting when the variable equals 3
You need a notify_one/all() (after line 21) to let the second thread getting out of its wait state.

Also due to line 13 do_click() will never end. You may use a global variable
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
bool shutdown = false;

...

void do_click()
{
    std::chrono::steady_clock::duration d = std::chrono::steady_clock::duration::zero(); 
    std::chrono::duration<int> one_second(1); 
    while (not shutdown)
    {
...
    }
}
int main()
{
...
  shutdown = true;
...
    return 0;
}


By the way: Even with notify you may miss click_counter == 3 because the scheduling of the thread is not predictable. So it might happen that click_counter is already 4 when click_listener() gets its timeslice.

And you should rather consider to use sleep instead of the loop. See:

http://www.cplusplus.com/reference/thread/this_thread/sleep_for
Last edited on
Topic archived. No new replies allowed.