threads

hello, I am here to ask why this code is not working properly
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
#include <thread>
#include <iostream>
#include <vector>

void check(int& val, bool& b)
{
    if (val == 9) b = true;
}

int main()
{
    int input;
    bool done = false;
    std::thread threads(check, std::ref(input), std::ref(done));
    while(!done)
    {
        std::cin >> input;
    }
    threads.join();
}


even if I input 9, the program is still running
fixed...but is this the right way ?

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

void check(int& val, bool& b, bool& run)
{
    while(run)
    {
        if (val == 9)
        {
            b = true;
            run = false;
        }
    }
}

int main()
{
    int input;
    bool done = false;
    bool run = !done;
    std::thread threads(check, std::ref(input), std::ref(done), std::ref(run));
    while(!done)
    {
        std::cin >> input;
    }
    threads.join();
}
but is this the right way ?
No. It will consume too much cpu time. Consider using condition_variable instead:

http://www.cplusplus.com/reference/condition_variable/condition_variable/
is this good ?

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
std::mutex mtx;
std::condition_variable cv;

void check(int& val, bool& b, bool& run)
{
    std::unique_lock<std::mutex> lck(mtx);
    while(!run) cv.wait(lck);
    while(run)
    {
        if (val == 9)
        {
            b = true;
            run = false;
        }
    }
}

void go(bool& b)
{
    std::unique_lock<std::mutex> lck(mtx);
    b = true;
    cv.notify_all();
}

int main()
{
    int input;
    bool done = false;
    bool run = false;
    std::thread threads(check, std::ref(input), std::ref(done), std::ref(run));
    go(run);
    while(!done)
    {
        std::cin >> input;
    }
    threads.join();
}
mutex, condition_variable, unique_lock et al are usually used with regards to concurrency but I don't see anything concurrent in your program at all. What is it exactly that you're trying to achieve or is this just an exercise in familiarization with these classes?
I am trying to be familiar with multithreading
also...I rarely read about mutex and this is the first time I heard about condition_variable...
so those mutex and condition_variable is important for multithreading am I right ?
a short introduction to concurrency would be in the eponymous chapter 18 in 'The C++ Standard Library (2nd edition)' by Nico Josuttis while a full-fledged book on that topic would be 'C++ Concurrency in Action – Practical Multithreading' by Anthony Williams
thank you for the reference but I doubt I can find that book around here...:(
I can only learn from internet...
Last edited on
I found these books on the internet as well ;))
I see
is this good ?
Nope. It is actually a bit tricky because of the need of mutual notification. This should be clean:
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
#include <iostream>
#include <thread>             // std::thread
#include <mutex>              // std::mutex, std::unique_lock
#include <condition_variable> // std::condition_variable

std::mutex mtx;
std::condition_variable cv;

void check(int& val, bool &done)
{
    std::unique_lock<std::mutex> lck(mtx);
    while(!done)
    {
        cv.wait(lck);
        done = (val == 9);
        cv.notify_all();
    }
    std::cout << "Done\n";
}

void go(bool& b)
{
    b = true;
}

int main()
{
    int input = 0;
    bool done = false;
    std::thread threads(check, std::ref(input), std::ref(done));
    while(!done)
    {
        std::cin >> input;
        std::unique_lock<std::mutex> lck(mtx);
        cv.notify_all();
        cv.wait(lck);
    }
    threads.join();
    std::cout << "End of program\n";
}
coder777: I was wondering (a) whether std::atomic<bool> instead of bool and (b) if go() is required any longer? Thanks,
@gunnerfunner

(a) To be consistent it is probably advisable to use atomic bool
(b) No.
Coder777: while writing the reply to the following thread ...
http://www.cplusplus.com/forum/beginner/218307/#msg1007225
... I recalled our conversation from a few days back and its only fair to mention that your use of plain (not atomic) bool in this case should be OK as the mutex ensures atomicity so to speak though there might be other reasons (as discussed through above link) for using std::atomic<bool>. And there should also be a check against spurious wakeups of condition variable (until C++17 comes fully into play I think) – so something on the following lines perhaps:
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
# include <iostream>
# include <mutex>
# include <future>
# include <condition_variable>

bool done;
std::mutex readyMutex;
std::condition_variable cv;

void check()
{
    int num{};
    do
    {
        std::cin >> num;
    } while (num != 9);
    {
        std::lock_guard<std::mutex> lg(readyMutex);
        done = true;
    }
    cv.notify_one();
}

int main()
{
    std::thread t(check);
    {
        std::unique_lock<std::mutex> ul{readyMutex};
        cv.wait(ul, []{return done; });
    }
    std::cout << "got 9 \n";	
    t.join(); // or t.detach();
}


And the same program using std::atomic<bool> (instead of bool) and std::future (instead of std::thread):
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
# include <iostream>
# include <mutex>
# include <future>
# include <condition_variable>

std::atomic<bool> done{false};
std::mutex readyMutex;
std::condition_variable cv;

void check()
{
    int num{};
    do
    {
        std::cin >> num;
    } while (num != 9);
    done.store(true);
}

int main()
{
    auto f = std::async(std::launch::async, check);

    while (!done.load())
    {
        std::this_thread::sleep_for(std::chrono::milliseconds(500));
    }
      std::cout << "got 9\n";
}
Topic archived. No new replies allowed.