我的问题是我不知道如何正确使用互斥体。我了解它在理论上是如何工作的,但我不知道为什么它在我的代码中不起作用。我想,如果我在var上使用互斥锁,它将被阻塞,直到被解锁。尽管如此,看来我仍然有一场数据竞赛。

我试图在类中定义一个互斥体和一个互斥体,它们通过引用传递给我。不知何故,这没有用。


class test {
public:
    void dosmth(std::mutex &a);
    int getT(){return t;};

private:
    int t = 0;
};


void test::dosmth(std::mutex &a) {
    for(;;){
        a.lock();
        t++;
        if(t==1000){
            t=0;
        }
        a.unlock();
    }
}

int main() {
    test te;
    std::mutex help;
    std::thread t(&test::dosmth, std::addressof(te), std::ref(help));
    for(;;){
        for (int i = 0; i <te.getT() ; ++i) {
            std::cout<<te.getT()<<std::endl;
        }
    }
}


结果应该是我得到了一些输出,所以现在我可以使用了。

最佳答案

仅当互斥锁用于控制所有将同时访问给定对象的critical sections代码的条目时,该互斥锁才能保证互斥。就您而言,您的第二个线程在主线程读取同一对象的值时修改了对象te.t的值。但是,只有一个线程正在使用互斥锁来保护对te.t的访问。对象te.t不是原子的。因此,您将进行数据争用,因此也将获得未定义的行为[intro.races]/21

您还必须在main的for(;;)循环中锁定和解锁互斥锁,例如:

    for(;;){
        help.lock();
        for (int i = 0; i <te.getT() ; ++i) {
            std::cout<<te.getT()<<std::endl;
        }
        help.unlock();
    }

或者更好,使用std::lock_guard:
    for(;;){
        std::lock_guard lock(help);
        for (int i = 0; i <te.getT() ; ++i) {
            std::cout<<te.getT()<<std::endl;
        }
    }

关于c++ - 如何正确使用互斥锁作为线程中成员函数的参数?,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/55697873/

10-15 01:37