【发布时间】:2021-06-30 08:26:28
【问题描述】:
我一直在尝试编写一个简单的程序来试验线程向量。我目前正在尝试创建一个线程,但我发现我遇到了一个错误,即我的构造函数没有正确初始化,错误是没有匹配参数列表的 std::thread 构造函数。这是我所做的:
#include <functional>
#include <iostream>
#include <numeric>
#include <thread>
#include <vector>
int sum = 0;
void thread_sum (auto it, auto it2, auto init) {
sum = std::accumulate(it, it2, init);
}
int main() {
// * Non Multi-Threaded
// We're going to sum up a bunch of numbers.
std::vector<int> toBeSummed;
for (int i = 0; i < 30000; ++i) {
toBeSummed.push_back(1);
}
// Initialize a sum variable
long sum = std::accumulate(toBeSummed.begin(), toBeSummed.end(), 0);
std::cout << "The sum was " << sum << std::endl;
// * Multi Threaded
// Create threads
std::vector<std::thread> threads;
std::thread t1(&thread_sum, toBeSummed.begin(), toBeSummed.end(), 0);
std::thread t2(&thread_sum, toBeSummed.begin(), toBeSummed.end(), 0);
threads.push_back(std::move(t1));
threads.push_back(std::move(t2));
return 0;
}
搞砸的行如下:
auto t1 =
std::thread {std::accumulate, std::ref(toBeSummed.begin()),
这是构造函数的问题。我尝试了 std::ref、std::function 和其他包装器的不同组合,并尝试将我自己的函数 lambda 对象作为累积的包装器。
以下是一些附加信息:
错误信息是:atomics.cpp:28:7: error: no matching constructor for initialization of 'std::thread'
此外,当悬停在构造函数上时,它告诉我第一个参数是
我尝试过的其他尝试:
- 使用引用而不是常规值参数
- 使用
std::bind - 使用
std::function - 在变量中声明函数并将其作为我的第一个参数传递给构造函数
- 使用不同的标志编译,例如
std=c++2a
编辑:
- 我会留下最初的问题,让其他人从我的错误中吸取教训。正如我接受的答案将显示的那样,这是由于我过度使用 auto。我读过一本 C++ 书,基本上说“总是使用 auto,它更易读!就像 Python 和动态类型,但具有 C++ 的性能”,但显然这不能总是做到。
using关键字提供了可读性,同时仍然安全。感谢您的回答!
【问题讨论】:
-
std::thread t1(, toBeSummed.begin(), toBeSummed.end(), 0);看起来坏了。它缺少第一个参数。 -
如果您想检索累加函数的结果,您可能更喜欢async 或packaged_task,它们可以为您提供未来的结果。
-
你的线程代码中有一些未定义的行为,你不要在启动它们之后加入线程,在退出之前加入它们,或者如果你有 c++20 的 jthread 可用,请改用它。跨度>
标签: c++ concurrency