Я снова увлекся изучением параллелизма и попытался решить эту проблему .
Короче, у меня есть класс и 3 функции. Мне нужно синхронизировать c их вызовы (необходимо напечатать FirstSecondThird
).
Это станет более понятным с кодом ниже:
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;
}
И угадайте, что мой вывод? Он печатает ThirdSecondFirst
.
Как это возможно? Разве этот код не склонен к DEADLOCK? Я имею в виду, что когда первый поток получил мьютекс в функции second
, не будет ли он ждать вечно, потому что теперь, когда мьютекс получен, мы не можем изменить переменную mfirst
?