c++ - 所有线程都做同样的事情。程序文件

标签 c++ multithreading vector

我是 CPP 的初学者,我们在类里面已经讨论了线程的主题。 我正在尝试使用它,但它似乎没有按照我想要的方式工作。

我希望每个线程将 j 的数量插入 vector 内,然后将 vector 打印到控制台。

看起来它们都打印了值“10”,这是循环结束后 j 保存的最后一个值。

vector<int> foo(int x) {
    vector<int> a;
    a.push_back(x);
    return a;
}

void print(vector<int> vec) {
    for (int i = 0; i<int(vec.size()); i++)
        cout << vec[i] <<endl;
}

void foo2(int x) {
    vector<int> b;
    thread thr([&] {b = foo(x); });
    thr.join();
    mtx1.lock();
    print(b);
    mtx1.unlock();
}

int main() {
    vector<thread> th;
    for (int j = 0; j < 10; j++)
        th.emplace_back(([&] {foo2(j); }));
    for (int j = 0; j < 10; j++)
        th[j].join();
}

注意:我希望线程 vector 将进入函数内部,调用一个新线程,该线程会将数字插入 vector ,然后打印。

我得到的输出是:

10
10
10
10
10
10
10
10
10
10

我的目标是:

0
1
2
3
4
5
6
7
8
9

感谢您的帮助。

最佳答案

for (int j = 0; j < 10; j++)
    th.emplace_back(([&] {foo2(j); }));

lambda 捕获 j通过引用(毕竟,这就是 [&] 的意思),lambda 被用来构造一个新的 std::thread ,还有这个for 立即循环迭代,递增 j .

但是,如果您仔细观察,您会注意到 j是通过引用捕获的,并且 C++ 无法保证新线程将读取 j 的值。 ,并调用foo2() ,在 for 之前父线程中的循环迭代并递增j .

这里发生的情况是,for 循环运行得足够快,因此它在所有线程实际开始自行运行之前完成,并且它们看到的只是 j 的最后一个值。 (甚至还不是这样,因为当这个 j 循环终止时,这个特定的 for 超出范围并被销毁,因为它被声明为 for 循环的本地,这在技术上意味着访问 j makes demons fly out of your nose ) .

解决方案:捕获j按值(即 [=][j] ),而不是引用。

附注即使这样做之后,您也无法保证从 0 到 9 的所有值都会按顺序打印。这完全取决于执行 std::cout << ... 的线程按照特定的顺序,同样,您绝对不能保证哪个线程将到达与所有其他线程相关的该语句。

关于c++ - 所有线程都做同样的事情。程序文件,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/62365600/

相关文章:

c++ - clang 重写器 : add structure definitions to invalid program

java - 超过锁定等待超时;尝试用 spring 和 Mysql 重启事务 Java

java - 代码被跳过

java - Thread 或 Runnable 如何立即被杀死

c++ - 如何将整个流读入 std::vector?

c++ - 类中的 std::vectors

c++ - g++ 编译选项 -std=c++14 编译错误显示 Werror=c++11-compat

c++ - OpenCV:使用霍夫圆变换检测虹膜

包含枚举的结构的 C++ 复制构造函数

C++ 传递 vector<vector<STRUCT>> 进行修改