首页 > 解决方案 > 参数引用适用于 lambda 但不适用于函数

问题描述

我不太确定我是否完全忘记了这里的基础知识,但是有人可以告诉我为什么在更改标志后只有 T1 停止?

#include <thread>
#include <iostream>

void job(const bool &flag)
{
    using namespace std::chrono_literals;
    while (flag)
    {
        std::cout << "Working T2" << '\n';
        std::this_thread::sleep_for(1s);
    }
}

int main(int argc, char const *argv[])
{
    bool flag = true;
    std::thread t1([&flag]()
                   {
                       using namespace std::chrono_literals;
                       while (flag)
                       {
                           std::cout << "Working T1" << '\n';
                           std::this_thread::sleep_for(1s);
                       }
                   });
    std::thread t2(job, flag);

    std::cin.get();
    flag = false;
    t1.join();
    t2.join();
    return 0;
}

我的理解是,两者都在访问同一块内存,因为标志作为参考被传递,所以作业函数不应该创建它自己的标志副本,而应该只访问传递给它的同一个标志,是这样吗不是这是如何工作的?非常感谢

标签: c++multithreadinglambdareference

解决方案


std::thread t2(job, flag);

这会制作一个副本flag并将该副本传递给job(). 为了使用参考,您需要使用std::ref

std::thread t2(job, std::ref(flag));

但为什么这是一个要求?

有几种不同的方式来看待它,但这里有一个相当简单的反例:

void job(const bool& val);

int main() {  
  // No problem
  job(true);
  
  // Would be broken if std::thread didn't make a copy.
  std::thread my_thread(job, true);
}

推荐阅读