繁体   English   中英

使用 std::condition_variable 同步调用函数

[英]Synchronized call of functions using std::condition_variable

我再次沉迷于学习并发并试图解决这个问题

简而言之,我有一个 class 和 3 个功能。 我需要同步他们的通话(需要打印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;
}

猜猜我的 output 是什么? 它打印ThirdSecondFirst

这怎么可能? 这段代码是不是容易出现死锁? 我的意思是,当第一个线程在 function second中获取互斥锁时,它不会永远等待,因为现在获取互斥锁我们不能更改变量mfirst吗?

你有一个非常微妙的错误。

std::thread t3((&Foo::third, t, printThird));

这条线不符合您的预期。 它仅使用一个参数printThird初始化线程,而不是使用您指定的 3 arguments 进行初始化。 那是因为您不小心使用了逗号表达式 结果, &Foo::thirdt就被丢弃了,甚至从未调用成员函数。

在您的代码中调用的唯一函数是printFirstprintSecondprintThird 如果没有任何同步,它们可能会以任意顺序打印。 您甚至可能会得到交错的 output。

std::thread t3{&Foo::third, t, printThird};

这是更正的版本。 花括号是为了避免编译器将其视为 function 声明,因为大多数令人烦恼的解析

作为旁注,如评论中所述,您使用错误的条件变量。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM