C++ c++;:错误:没有名为‘;类型’;在‘;类别标准::结果<;void(*(标准::无序)
下面是一个简单的程序,使用两个线程插入一个哈希表进行测试C++ c++;:错误:没有名为‘;类型’;在‘;类别标准::结果<;void(*(标准::无序),c++,multithreading,c++11,C++,Multithreading,C++11,下面是一个简单的程序,使用两个线程插入一个哈希表进行测试 #include <iostream> #include <unordered_map> #include <thread> using namespace std; void thread_add(unordered_map<int, int>& ht, int from, int to) { for(int i = from; i <= to; ++i)
#include <iostream>
#include <unordered_map>
#include <thread>
using namespace std;
void thread_add(unordered_map<int, int>& ht, int from, int to)
{
for(int i = from; i <= to; ++i)
ht.insert(unordered_map<int, int>::value_type(i, 0));
}
void test()
{
unordered_map<int, int> ht;
thread t[2];
t[0] = thread(thread_add, ht, 0, 9);
t[1] = thread(thread_add, ht, 10, 19);
t[0].join();
t[1].join();
std::cout << "size: " << ht.size() << std::endl;
}
int main()
{
test();
return 0;
}
#包括
#包括
#包括
使用名称空间std;
无效线程添加(无序映射&ht、int-from、int-to)
{
对于(int i=from;i这个错误确实非常隐晦,但问题是thread\u add
通过引用获取它的第一个参数,但您通过值传递它。这会导致函子类型推断错误。如果您想通过引用将某个对象传递给std::bind
或std::thread
,您需要使用引用包装器(std::ref
):
我可以使用MSVC2013成功编译您的代码。但是,thread()
将其参数的副本传递给新线程。这意味着,如果您的代码将在编译器上编译,则每个线程将使用其自己的ht
副本运行,因此在最后,main
的ht
将为空
GCC没有使用这个奇怪的消息进行编译。您可以使用带有线程的引用包装器来消除它:
t[0] = thread(thread_add, std::ref(ht), 0, 9);
t[1] = thread(thread_add, std::ref(ht), 10, 19);
这将成功编译。线程使用的每个引用都将引用同一个对象
但是,您很可能会得到一些运行时错误或意外结果。这是因为两个线程同时尝试插入到ht
中。但是无序的\u map
不是线程安全的,因此这些竞速条件可能会导致ht
达到不稳定状态(即UB,即潜在SEGFULT)
要使其正常运行,您必须保护您的concurent访问:
#include <mutex>
...
mutex mtx; // to protect against concurent access
void thread_add(unordered_map<int, int>& ht, int from, int to)
{
for (int i = from; i <= to; ++i) {
std::lock_guard<std::mutex> lck(mtx); // protect statements until end of block agains concurent access
ht.insert(unordered_map<int, int>::value_type(i, 0));
}
}
#包括
...
mutex mtx;//防止并发访问
无效线程添加(无序映射&ht、int-from、int-to)
{
对于(inti=from;顺便说一句,clang并没有好多少(尝试使用删除的函数),但至少它会将您带到参数元组的解包位置,这是我猜想的。不相关,但通过引用传递将在ht
@Snps上创建数据竞争我接受了OP的“for test no lock is used”语句这意味着他们打算在“上线”时提供锁。可能重复:相关:
t[0] = thread(thread_add, std::ref(ht), 0, 9);
t[1] = thread(thread_add, std::ref(ht), 10, 19);
#include <mutex>
...
mutex mtx; // to protect against concurent access
void thread_add(unordered_map<int, int>& ht, int from, int to)
{
for (int i = from; i <= to; ++i) {
std::lock_guard<std::mutex> lck(mtx); // protect statements until end of block agains concurent access
ht.insert(unordered_map<int, int>::value_type(i, 0));
}
}