std::线程传递向量元素(按引用)

std::thread pass vector element by reference

本文关键字:元素 引用 向量 线程 std      更新时间:2023-10-16

我试图弄清楚为什么以下工作:

threaded thr[8] = { threaded(), threaded() ,threaded() ,threaded() ,threaded() ,threaded() ,threaded() ,threaded() };
std::vector<std::thread> vec;
for (int i = 0; i < threads; i++)
{
    vec.push_back(std::thread(&threaded::calc, &thr[i], i, num_samples));
}

而以下则没有:

std::vector<threaded> thr;
std::vector<std::thread> vec;
for (int i = 0; i < threads; i++)
{
    thr.push_back(threaded());
    vec.push_back(std::thread(&threaded::calc, &thr[i], i, num_samples));
}

我尝试使用 std::ref 而不是 &- 它仍然不起作用。以下是线程的定义:

struct threaded
{
    float elapsed1 = 0;
    float elapsed2 = 0;
    float res = 0;
    float res_jit = 0;
    void calc(int thread, int num_samples){//do something}
};

通过不起作用,我的意思是,当使用矢量和 &,我遇到内存访问冲突,当我尝试使用 std::ref(thr[i]) 而不是 &,它不想编译以下错误:

Error   C2672   'std::invoke': no matching overloaded function found        

Error   C2893   Failed to specialize function template 'unknown-type std::invoke(_Callable &&,_Types &&...)'        

如果我只使用 thr[i],它可以正常工作,但我想修改线程类的值,所以我真的不想传递副本。

随着向量thr随着每次push_back调用而变大,最终超过保留内存区域的容量,它需要重新分配其存储并将其元素复制(或移动)到新分配的空间。一旦发生这种情况,对象开始存在于新的内存地址下,因此先前获得的地址将失效。为了防止搬迁,请在进入环路之前预留足够的空间:

std::vector<threaded> thr;
thr.reserve(threads);

或者默认一次构造所有元素:

std::vector<threaded> thr(threads);