休眠生成的线程

Sleeping a spawned thread

我想生成一个循环并不断检查是否按下了键的线程。我试过了:

void EventHandler::listenForPresses(int loopMSDelay) {
    listenOnKeys = true;
    listeningThread = std::thread ([&]{
        do {

            std::cout << "Looped!\n";
            updatePressedKeys();
            actOnPressedKeys();
            std::this_thread::sleep_for(std::chrono::milliseconds(loopMSDelay));

        } while (listenOnKeys);
    });
}

问题是,sleep_for 在这种情况下有非常奇怪的行为;它似乎永久挂起生成的线程而不是休眠 loopMSDelay 毫秒。

没有 std::this_thread::sleep_for... 行(注释掉),它运行良好(尽管它循环比我想要的快得多)。

虽然在上面的行中,它显示了一次 "Looped!" 消息,然后再也不会显示("never",我等了几分钟,什么也没有)。这表明它出于某种原因冻结在睡眠线上。

我唯一能想到的是它得到 "confused" 因为我在主线程(在 this_thread 命名空间)的 lambda 中调用 sleep_for,但是期望它休眠生成的线程。

最好的解决办法是什么?我读到 this_thread::sleep_for 是首选的睡眠方式(当睡眠合适时),所以自从再次拿起 C++ 以来我一直使用它。

您的 lambda 通过引用捕获 loopMSDelay,这是一个函数参数,其生命周期在函数调用结束时结束。

这意味着您的线程将持有悬空引用,并且在尝试使用它时会出现未定义的行为。实际上,它可能将一些随机的大数(驻留在 loopMSDelay 曾经所在的位置)传递给 sleep_for,这解释了您观察到的内容。

使用[=]按值捕获。