[英]Synchronized call of functions using std::condition_variable
I got addicted to learning concurrency again and tried to solve this problem .我再次沉迷于学习并发并试图解决这个问题。
In short, I have a class and 3 functions.简而言之,我有一个 class 和 3 个功能。 I need to sync their calls (need to print
FirstSecondThird
).我需要同步他们的通话(需要打印
FirstSecondThird
)。
It will become more clear with the code below:使用下面的代码会更清楚:
std::function<void()> printFirst = []() { std::cout << "First"; };
std::function<void()> printSecond = []() { std::cout << "Second"; };
std::function<void()> printThird = []() { std::cout << "Third"; };
class Foo {
std::condition_variable cv;
bool mfirst,msecond;
std::mutex mtx;
public:
Foo() {
mfirst = false;
msecond = false;
}
void first(std::function<void()> printFirst) {
std::unique_lock<std::mutex> l(mtx);
printFirst();
mfirst = true;
}
void second(std::function<void()> printSecond) {
std::unique_lock<std::mutex> l(mtx);
cv.wait(l, [this]{return mfirst == true; });
printSecond();
msecond = true;
}
void third(std::function<void()> printThird) {
std::unique_lock<std::mutex> l(mtx);
cv.wait(l, [this] {return (mfirst && msecond) == true; });
printThird();
}
};
int main()
{
Foo t;
std::thread t3((&Foo::third, t, printThird));
std::thread t2((&Foo::second, t, printSecond));
std::thread t1((&Foo::first, t, printFirst));
t3.join();
t2.join();
t1.join();
return 0;
}
And guess what my output is?猜猜我的 output 是什么? It prints
ThirdSecondFirst
.它打印
ThirdSecondFirst
。
How is this possible?这怎么可能? Isn't this code prone to DEADLOCK?
这段代码是不是容易出现死锁? I mean, when the first thread acquired the mutex in function
second
, wouldn't it wait forever because now as mutex is acquired we cannot change variable mfirst
?我的意思是,当第一个线程在 function
second
中获取互斥锁时,它不会永远等待,因为现在获取互斥锁我们不能更改变量mfirst
吗?
You have a very subtle bug.你有一个非常微妙的错误。
std::thread t3((&Foo::third, t, printThird));
This line does not do what you expect.这条线不符合您的预期。 It initializes a thread with only one argument,
printThird
, instead of initializing with the 3 arguments you specified.它仅使用一个参数
printThird
初始化线程,而不是使用您指定的 3 arguments 进行初始化。 That's because you accidentally used a comma expression .那是因为您不小心使用了逗号表达式。 As a result,
&Foo::third
and t
are just discarded, and the member functions are never even called.结果,
&Foo::third
和t
就被丢弃了,甚至从未调用成员函数。
The only functions that are called in your code are printFirst
, printSecond
, and printThird
.在您的代码中调用的唯一函数是
printFirst
、 printSecond
和printThird
。 Without any synchronization, they may print in arbitrary order.如果没有任何同步,它们可能会以任意顺序打印。 You may even get interleaved output.
您甚至可能会得到交错的 output。
std::thread t3{&Foo::third, t, printThird};
Here is the corrected version.这是更正的版本。 The curly braces are for avoiding the compiler treating this as a function declaration because of most vexing parse
花括号是为了避免编译器将其视为 function 声明,因为大多数令人烦恼的解析
As a side note, as mentioned in the comments, you are using condition variables wrong.作为旁注,如评论中所述,您使用错误的条件变量。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.