author:
- luixiao1223
title: chapter02
Choosing the number of threads at runtime
- thread::hardware_concurrency()可以获得硬件支持的线程数量,不过也可能返回0表示,系统为提供此类接口)但是这个只是参考值.实际不一定能够准确.
- 为什么需要知道cpu支持的物理线程数量?因为过多的线程运行在有限的物理线程上会发生频繁的资源切换.会影响效率.
(多线程版累加算法)
template<typename Iterator,typename T>
struct accumulate_block
{
void operator()(Iterator first,Iterator last,T& result)
{
result=std::accumulate(first,last,result);
}
};
template<typename Iterator,typename T>
T parallel_accumulate(Iterator first,Iterator last,T init)
{
unsigned long const length=std::distance(first,last);//(sai:std::distance的用法)
if(!length) //<--1
return init;
unsigned long const min_per_thread=25;
unsigned long const max_threads=
(length+min_per_thread-1)/min_per_thread; //<--2
unsigned long const hardware_threads=
std::thread::hardware_concurrency();
unsigned long const num_threads= //<--3
std::min(hardware_threads!=0?hardware_threads:2,max_threads);
unsigned long const block_size=length/num_threads; //<--4
std::vector<T> results(num_threads);
std::vector<std::thread> threads(num_threads-1); //<--5
Iterator block_start=first;
for(unsigned long i=0;i<(num_threads-1);++i)
{
Iterator block_end=block_start;
std::advance(block_end,block_size); //<--6
//(std:advance的用法)
threads[i]=std::thread( //<--7
accumulate_block<Iterator,T>(),
block_start,block_end,std::ref(results[i]));
//从线程中获得数据的方法只有串ref和以后要且少的future.
block_start=block_end; //<--8
}
accumulate_block<Iterator,T>()(
block_start,last,results[num_threads-1]); //<--9
std::for_each(threads.begin(),threads.end(),
std::mem_fn(&std::thread::join)); //<--10
return std::accumulate(results.begin(),results.end(),init); //<--11
}
如何去推断一个变量的类型?
最简单的办法就是给它赋一个非法的值.这个时候编译器会报错.报错信息里面有类型信息.
Identifying threads
-
获取线程id的方法,通过线程累的成员函数get_id(),以及通过在线程函数中使用std::this_thread::get_id()函数
-
std::thread:id对象是可以比较和可以作为key值的,比如std::hash<std::thread::id>
-
如何判断代码运行区块是处于父线程还是子线程.
std::thread::id master_thread; void some_core_part_of_algorithm() { if(std::this_thread::get_id()==master_thread) { do_master_thread_work(); } do_common_work(); }//(可以使用get_id()来决定父线程是谁,是否需要做一些特殊工作)
-
你也可以打印出来,但是没什么意义.各种编译器可能不一样.这个打印出来的值,没有什么语义上的意义.
std::cout<<std::this_thread::get_id();