use*_*598 29 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)
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;
}
Run Code Online (Sandbox Code Playgroud)
但是,编译时会出错.
$ g++ -std=c++11 -pthread test.cpp
...
/usr/include/c++/4.8.2/functional:1697:61: error: no type named ‘type’ in ‘class std::result_of<void (*(std::unordered_map<int, int>, int, int))(std::unordered_map<int, int>&, int, int)>’
typedef typename result_of<_Callable(_Args...)>::type result_type;
...
Run Code Online (Sandbox Code Playgroud)
花了一段时间,但仍然无法纠正它.谢谢.
Chr*_*phe 36
我可以使用MSVC2013成功编译您的代码.但是,thread()将其参数的副本传递给新线程.这意味着,如果你的代码将编译你的编译器,每个线程wourd有自己的副本上运行ht,因此,在年底,main的ht将是空的.
GCC不会使用这个奇怪的消息进行编译.你可以通过使用带线程的引用包装器来摆脱它:
t[0] = thread(thread_add, std::ref(ht), 0, 9);
t[1] = thread(thread_add, std::ref(ht), 10, 19);
Run Code Online (Sandbox Code Playgroud)
这将成功编译.并且线程使用的每个引用都将引用相同的对象.
但是,很有可能会出现运行时错误或意外结果.这是因为两个线程正在努力插入ht.但是unordered_map不是线程安全的,因此这些竞争条件可能导致ht达到不稳定状态(即UB,即潜在的段错误).
为了使其正常运行,您必须保护您的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));
}
}
Run Code Online (Sandbox Code Playgroud)
Rei*_*ica 25
这个错误确实很神秘,但问题是thread_add它通过引用获取它的第一个参数,但是你按值传递它.这会导致仿函数类型推断错误.如果你想通过引用传递一些实际的函数std::bind或者像a 的main函数那样std::thread,你需要使用一个引用包装器(std::ref):
void test()
{
// ...
t[0] = thread(thread_add, std::ref(ht), 0, 9);
t[1] = thread(thread_add, std::ref(ht), 10, 19);
// ...
}
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
32878 次 |
| 最近记录: |