C ++在不同线程中更改向量

时间:2018-10-27 22:27:40

标签: c++ multithreading c++11

我试图在另一个线程中更改矢量,但是矢量的值未更改。我试图寻找答案,我认为使用std :: ref可以解决此问题,但是没有用。

**编辑:更简单的代码

这是启动线程的代码:

printf("tmp size: %d\n", tmp_size);
printf("before change");
printArray(tmp);
std::thread threads[1];
for(int i = 0; i < 1; i++){
    threads[i] = std::thread(callback,  std::ref(tmp));
}

for(int i = 0; i < 1; i++){
    threads[i].join();
}

printf("after join: ");
printArray(tmp);

这是回调:

void callback(std::vector<uint64_t>  tmp){

    tmp[0] = 1;
    printf("inside callback");
    printArray(tmp);
}

,输出为:

tmp size: 2
before change 0 0
inside callback 1 0
after join:  0 0

我期望线程更改向量后,其值将为:内部回调:10。不是通过引用传递的吗?

2 个答案:

答案 0 :(得分:1)

您正在传递对该函数的引用,但随后该函数按值获取其参数,并为其指定引用的值。修改引用的值没有好处。您需要修改参考。这是如何正确执行的演示:

#include <vector>
#include <stdint.h>
#include <thread>

void callback(std::vector<uint64_t> &tmp)
{
    tmp[0] += 1;
}

int main()
{
    std::thread threads[1];
    std::vector<uint64_t> tmp;
    tmp.push_back(1);
    for(int i = 0; i < 1; i++)
        threads[i] = std::thread(callback,  std::ref(tmp));

    for(int i = 0; i < 1; i++)
        threads[i].join();
    printf("%d\n", (int) tmp[0]);
}

答案 1 :(得分:0)

如果您想让回调函数更改矢量,则必须通过指针或引用传递它。

您的回调代码代替了它。

有时可能是线程安全的另一个选项是,如果要将向量“移动”到线程中,然后在线程完成时将其移回。像这样:

#include <thread>
#include <future>
#include <vector>
#include <iostream>

std::vector<int> addtovec(std::vector<int> vec, int add) {
    for(auto &x: vec) {
        x += add;
    }
    return vec;
}

std::ostream& operator<<(std::ostream& os, const std::vector<int> &v) {
    os << '{';
    bool comma = false;
    for(const auto &x: v) {
        if(comma) os << ',';
        comma = true;
        os << x;
    }
    os << '}';
    return os;
}

int main() {
    std::vector<int> a{1,2,3,9,8,7};
    std::cout << "before: " << a << std::endl;

    auto future = std::async(addtovec, std::move(a), 5);
    std::cout << "after move: " << a << std::endl;
    a = future.get();

    std::cout << "after get: " << a << std::endl;
    return 0;
}