-1

我在leetcode中遇到了一个问题。我在讨论中查看了一些解决方案。但我的解决方案与其他解决方案不同,因为我没有使用lockin 方法first。我想知道我的代码是否正确。此外,你能给我一些关于我的代码的建议吗?

我认为没有必要在类似unique_lock的方法中使用,对吗?void first(function<void()> printFirst)void second(function<void()> printSecond)

class Foo {
public:
    Foo() {

    }

    void first(function<void()> printFirst) {
        // cout<<1<<endl;
        // printFirst() outputs "first". Do not change or remove this line.
        // mtx.lock();
        printFirst();
        flag=1;
        // mtx.unlock();
        cond.notify_all();
        // cout<<11<<endl;
    }

    void second(function<void()> printSecond) {
        // cout<<2<<endl;
        {
            unique_lock<mutex> lk(mtx);
            cond.wait(lk,[this](){return flag==1;});
            // printSecond() outputs "second". Do not change or remove this line.
            printSecond();
            flag=2;
        }

        // cout<<22<<endl;
        cond.notify_all();
    }

    void third(function<void()> printThird) {
        // cout<<3<<endl;
        unique_lock<mutex> lk(mtx);
        cond.wait(lk,[this](){return flag==2;});
        // printThird() outputs "third". Do not change or remove this line.
        printThird();
        flag=3;
        // cout<<33<<endl;
    }

    mutex mtx;
    condition_variable cond;
    int flag=0;
};
4

3 回答 3

2

显然,您的三个元素函数应该由不同的线程调用。因此,您需要锁定每个线程中的互斥锁以保护公共变量flag不被并发访问。所以你应该取消注释mtx.lock()mtx.unlock()first那里保护它。函数secondthird应用 aunique_lock作为替代方案。

始终确保在调用之前解锁互斥锁,cond.notify_all()方法是调用mtx.unlock()before 或制作unique_lock内部代码块的局部变量,如second.

进一步的建议

private:在类定义底部的元素变量之前放置一个,以保护它们免受外部访问。这将确保flag在不锁定互斥锁的情况下无法更改。

于 2019-08-27T12:05:33.833 回答
1

有必要。

您的代码在这种情况下产生了正确的输出是不重要的。完全有可能在调用printFirst的时候可能还不完整。printSecond您需要互斥锁来防止这种情况并停止printSecondprintThird。从同时运行。

于 2019-08-27T11:59:25.123 回答
1

或中的flag检查条件可以与分配给的同时进行评估。second()third()first()1flag

重写这个

cond.wait(lk, [this](){return flag==1;});

像这样,可能更容易看到:

while(!(flag==1)) cond.wait(lk);

wait()它和你的 lambda做同样的事情。

flag应该在持有互斥锁时读取 - 但first不关心互斥锁并随时分配给flag它。对于非原子类型,这是一场灾难。它可能会工作10000000 次(并且可能会) - 但是当事情实际上同时发生时(因为你允许它) -繁荣- 未定义的行为

于 2019-08-27T13:41:04.617 回答