Considering the following, simple code:
using ms = std::chrono::milliseconds;
int val = 0;
for(;;)
{
std::cout << val++ << ' ';
std::this_thread::sleep_for(ms(200));
}
We see that we infinitely print subsequent numbers each 0.2 second.
Now, I would like to implement the same logic using a helper class and multithreading. My aim is to be able to run something similar to this:
int main()
{
Foo f;
std::thread t1(&Foo::inc, f);
std::thread t2(&Foo::dis, f);
t1.join();
t2.join();
}
where Foo::inc()
will increment a member variable val
of an object f
by 1
and Foo::dis()
will display the same variable.
Since the original idea consisted of incrementing and printing the value infinitely, I would assume that both of those functions must contain an infinite loop. The problem that could occur is data race - reading and incrementing the very same variable. To prevent that I decided to use std::mutex
.
My idea of implementing Foo
is as follows:
class Foo {
int val;
public:
Foo() : val{0} {}
void inc()
{
for(;;){
mtx.lock();
++val;
mtx.unlock();
}
}
void dis()
{
using ms = std::chrono::milliseconds;
for(;;){
mtx.lock();
std::cout << val << ' ';
std::this_thread::sleep_for(ms(200));
mtx.unlock();
}
}
};
Obviously it's missing the mtx
object, so the line
std::mutex mtx;
is written just under the #include
s, declaring mtx
as a global variable.
To my understanding, combining this class' definition with the above main()
function should issue two, separate, infinite loops that each will firstly lock the mutex, either increment or display val
and unlock the mutex so the other one could perform the second action.
What actually happens is instead of displaying the sequence of 0 1 2 3 4...
it simply displays 0 0 0 0 0...
. My guess is that I am either using std::mutex::lock
and std::mutex::unlock
incorrectly, or my fundamental understanding of multithreading is lacking some basic knowledge.
The question is - where is my logic wrong?
-
How would I approach this problem using a helper class and two
std::thread
s with member functions of the same object? -
Is there a guarantee that the incrementation of
val
and printing of it will each occur one after the other using this kind of logic? i.e. will there never be a situation whenval
is incremented twice before it being displayed, or vice versa?
Aucun commentaire:
Enregistrer un commentaire