c++ - C++多线程中的锁和条件变量问题

标签 c++ multithreading locking mutex condition-variable

我正在尝试用 C++(Windows 10、Visual Studio Express)实现一个简单的多线程示例。

我有线程 T1 计算 z = x * x,其中 x 和 z 是全局变量。 线程 T2 显示 z

我想使用锁和条件变量。

由于某些原因,执行在 T1 未被阻止时卡住(在 cv.wait 之后,可能在 while 循环中——高 CPU 使用率)。但是当我在 cout << "x" << endl; 之前添加一些代码(我尝试使用 cv.notify_one(); )时,不会发生这种情况。在 main() 中。这很奇怪。

预先感谢您的帮助!

这是代码。我删除了我用来杀死线程的部分,因为我没有接触到算法的那部分——问题在之前。

#include "stdafx.h"
#include <iostream>
#include <thread>
#include <mutex>
#include <condition_variable>

using namespace std;

mutex m;
condition_variable cv;
bool datax = 0, dataz = 0, zPrinted = 0;

void T1(const int& x, int& z)
{
    do {
        unique_lock<mutex> lk(m);
        cv.wait(lk, [] {return (datax); });
        if (datax) {
            z = x * x;
            datax = 0;
            dataz = 1;
            lk.unlock();
            while (dataz)
                cv.notify_one();
        }
    } while (1);
}

void T2(const int& z)
{
    do {
        unique_lock<mutex> lk(m);
        cv.wait(lk, [] {return (dataz); });
        if (dataz) {
            cout << "z = " << z << endl;
            dataz = 0;
            zPrinted = 1;
            lk.unlock();
            while (zPrinted)
                cv.notify_one();
        }
    } while (1);
}

int main()
{
    int x, z;
    char c;
    thread threadT1(T1, cref(x), ref(z));
    thread threadT2(T2, cref(z));
    do {
        unique_lock<mutex> lk(m);
        cout << "Enter x: ";
        cin >> x;
        datax = 1;
        lk.unlock();
        while (datax) {
            cv.notify_one();
        }
        cv.wait(lk, [] {return zPrinted; });
        zPrinted = 0;
        cout << "Continue? (y/n): ";
        cin >> c;
    } while (c == 'y');
    return 0;
}

最佳答案

问题出在这里:

lk.unlock();
while (datax) {
  cv.notify_one();
}
cv.wait(lk, [] {return zPrinted; }); // <-- waiting on unlocked mutex
zPrinted = 0;

您正在等待解锁的互斥体,这是未定义的行为 see here under notes .

关于c++ - C++多线程中的锁和条件变量问题,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/50600409/

相关文章:

c++ - 如何在 Linux 上从源代码安装 TBB 并使其工作

java - 等待一个线程以.join不一致结束

JavaFX - ErrorStream 到标签中

C# 线程访问 if block ,其条件返回 false

java - 通过java锁定数组中的每个项目

c++ - 控制台显示字符串结尾字符

c++ - 删除双链循环列表时出错

c++ - 使用 Vectors 创建对象时如何调用析构函数

java - Thread.interrupted() 返回的值不正确 - 为什么?

c# - 我可以使用字典元素作为锁定对象吗?