Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/cplusplus/160.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C++ 简单的多线程示例,我可以';我不明白为什么行为会根据我在cv.wait()中使用谓词的方式发生变化_C++_Multithreading_Condition Variable - Fatal编程技术网

C++ 简单的多线程示例,我可以';我不明白为什么行为会根据我在cv.wait()中使用谓词的方式发生变化

C++ 简单的多线程示例,我可以';我不明白为什么行为会根据我在cv.wait()中使用谓词的方式发生变化,c++,multithreading,condition-variable,C++,Multithreading,Condition Variable,我的代码在下面。这是一个简单的例子,使用3个线程打印多达2N的交替数字。一个打印0,一个打印奇数,一个打印偶数。例如,向控制台输入2个输出0102。目前代码是有效的,但是我有一个问题只是为了我的理解 例如,在奇数函数中,如果我更改 while (!(print_zero == 0 && print_odd == 1)) { cv.wait(lck); } 到 我再也不能得到一致的正确行为了,相反,有时它会死锁,有时

我的代码在下面。这是一个简单的例子,使用3个线程打印多达2N的交替数字。一个打印0,一个打印奇数,一个打印偶数。例如,向控制台输入2个输出0102。目前代码是有效的,但是我有一个问题只是为了我的理解

例如,在奇数函数中,如果我更改

            while (!(print_zero == 0 && print_odd == 1)) {
            cv.wait(lck);
        }

我再也不能得到一致的正确行为了,相反,有时它会死锁,有时它会以一种奇怪的顺序打印出来。但在我看来,它似乎应该是相同的,而且逻辑是相同的。有人知道为什么会这样吗

#include <condition_variable>
#include <mutex>
#include <iostream>
#include <atomic>

using namespace std;

class ZeroEvenOdd {
private:
    int n;
    mutex mtx;
    condition_variable cv;
    int print_zero, print_even, print_odd;

public:
    ZeroEvenOdd(int n) {
        this->n = n;
        print_zero = 1;
        print_even = 0;
        print_odd = 1;
    }

    void printNumber(int x) {
        cout << x << endl;
    }

    // printNumber(x) outputs "x", where x is an integer.
    void zero( ) {
        for (int p = 0; p < n; p++) {
            std::unique_lock<std::mutex> lck(mtx);

            while (print_zero == 0) {
                cv.wait(lck);
            }
            printNumber(0);
            print_zero = 0;
            cv.notify_all();

        }
    }

    void even( ) {
        //2
        for (int j = 2; j <= n; j += 2) {
            std::unique_lock<std::mutex> lck(mtx);

            while (!(print_zero == 0 && print_even == 1)) {
                cv.wait(lck);
            }
            printNumber(j);
            print_zero = 1;
            print_even = 0;
            print_odd = 1;
            cv.notify_all();
        }
    }

    void odd() {
        //3
        for (int i = 1; i <= n; i += 2) {
            std::unique_lock<std::mutex> lck(mtx);
            //doesnt work
            //while (print_zero == 1 && print_odd == 0) {
            //    cv.wait(lck);
            //}
            while (!(print_zero == 0 && print_odd == 1)) {
                cv.wait(lck);
            }
            printNumber(i);
            print_zero = 1;
            print_even = 1;
            print_odd = 0;
            cv.notify_all();
        }
    }
};

int main()
{
    std::cout << "Hello World!\n";
    ZeroEvenOdd object(10);
    std::thread t1(&ZeroEvenOdd::zero, &object);
    std::thread t3(&ZeroEvenOdd::odd, &object);
    std::thread t2(&ZeroEvenOdd::even, &object);


    t1.join();
    t2.join();
    t3.join();

    cout << "done" << endl;
}
#包括
#包括
#包括
#包括
使用名称空间std;
类零偶奇数{
私人:
int n;
互斥mtx;
条件变量cv;
int print_zero、print_偶数、print_奇数;
公众:
零偶奇数(整数n){
这个->n=n;
打印_zero=1;
打印_偶数=0;
打印奇数=1;
}
无效打印编号(整数x){

摩根定律:
p和q
相当于
not((not p)或(not q))
。你的两个条件一开始就不相等。摩根定律:
p和q
相当于
not((not p)或(not q))
。你的两个条件一开始就不相等。
#include <condition_variable>
#include <mutex>
#include <iostream>
#include <atomic>

using namespace std;

class ZeroEvenOdd {
private:
    int n;
    mutex mtx;
    condition_variable cv;
    int print_zero, print_even, print_odd;

public:
    ZeroEvenOdd(int n) {
        this->n = n;
        print_zero = 1;
        print_even = 0;
        print_odd = 1;
    }

    void printNumber(int x) {
        cout << x << endl;
    }

    // printNumber(x) outputs "x", where x is an integer.
    void zero( ) {
        for (int p = 0; p < n; p++) {
            std::unique_lock<std::mutex> lck(mtx);

            while (print_zero == 0) {
                cv.wait(lck);
            }
            printNumber(0);
            print_zero = 0;
            cv.notify_all();

        }
    }

    void even( ) {
        //2
        for (int j = 2; j <= n; j += 2) {
            std::unique_lock<std::mutex> lck(mtx);

            while (!(print_zero == 0 && print_even == 1)) {
                cv.wait(lck);
            }
            printNumber(j);
            print_zero = 1;
            print_even = 0;
            print_odd = 1;
            cv.notify_all();
        }
    }

    void odd() {
        //3
        for (int i = 1; i <= n; i += 2) {
            std::unique_lock<std::mutex> lck(mtx);
            //doesnt work
            //while (print_zero == 1 && print_odd == 0) {
            //    cv.wait(lck);
            //}
            while (!(print_zero == 0 && print_odd == 1)) {
                cv.wait(lck);
            }
            printNumber(i);
            print_zero = 1;
            print_even = 1;
            print_odd = 0;
            cv.notify_all();
        }
    }
};

int main()
{
    std::cout << "Hello World!\n";
    ZeroEvenOdd object(10);
    std::thread t1(&ZeroEvenOdd::zero, &object);
    std::thread t3(&ZeroEvenOdd::odd, &object);
    std::thread t2(&ZeroEvenOdd::even, &object);


    t1.join();
    t2.join();
    t3.join();

    cout << "done" << endl;
}