C++并发编程——在运行时选择线程数量
来源:互联网 发布:泰豪软件股份有限公司 编辑:程序博客网 时间:2024/05/29 15:17
在编写多线程程序时,运行多少线程比较合适呢?线程并不是越多越好,理论上,硬件支持多少线程数,就开多少个线程比较合适,有的比如完成端口IOCP中建议开2倍线程数,因为考虑到有些线程可能会挂起等情况。但最重要的一条,首先要获取当前硬件支持的线程数,通常情况下为CPU核数。
std::thread::hardware_concurrency(); //获取当前CPU核心数量
代码示例:
以下代码为std::accumulate的简单并行版本实现,通过将大量的累加操作,分配给多个线程去计算,最后将各个线程计算的结果累加,得出最终结果。真正的并行计算任务分割是很麻烦的,这里并不需要考虑线程的同步等问题。
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); if(!length) return init; unsigned long const min_per_thread=25; unsigned long const max_threads=(length+min_per_thread-1)/min_per_thread; //获取最大线程数量 unsigned long const hardware_threads=std::thread::hardware_concurrency(); //获取当前CPU核心数量 unsigned long const num_threads=std::min(hardware_threads!=0?hardware_threads:2,max_threads);//运行线程数量 unsigned long const block_size=length/num_threads; std::vector<T> results(num_threads); Iterator block_start=first; std::vector<std::thread> v_threads(num_threads-1); for(unsigned long i=0;i<num_threads-1;++i) { Iterator block_end=block_start; std::advance(block_end,block_size); v_threads[i]=std::thread(accumulate_block<Iterator,T>(),block_start,block_end,std::ref(results[i])); block_start=block_end; } accumulate_block<Iterator,T>()(block_start,last,results[num_threads-1]); //计算剩下的数,相当于在主线程中计算 std::for_each(v_threads.begin(),v_threads.end(),std::mem_fn(&std::thread::join));//等待所有线程计算完成 return std::accumulate(results.begin(),results.end(),init);}int _tmain(int argc, _TCHAR* argv[]){ std::vector<int> v(100000); std::iota(v.begin(),v.end(),1); long long sum=parallel_accumulate(v.begin(),v.end(),0); cout<<"sum="<<sum<<endl; return 0;}
相关STL源码:
//std::distance源码template<class _BidIt, class _Diff> inline void _Distance2(_BidIt _First, _BidIt _Last, _Diff& _Off, bidirectional_iterator_tag) { // add to _Off distance between bidirectional iterators (redundant) for (; _First != _Last; ++_First) ++_Off; }template<class _InIt> inline typename iterator_traits<_InIt>::difference_type distance(_InIt _First, _InIt _Last) { // return distance between iterators typename iterator_traits<_InIt>::difference_type _Off = 0; _Distance2(_First, _Last, _Off, _Iter_cat(_First)); return (_Off); }
//std::advance源代码 // TEMPLATE FUNCTION advancetemplate<class _InIt, class _Diff> inline void _Advance(_InIt& _Where, _Diff _Off, input_iterator_tag) { // increment iterator by offset, input iterators #if _ITERATOR_DEBUG_LEVEL == 2 if (_Off < 0) _DEBUG_ERROR("negative offset in advance"); #endif /* _ITERATOR_DEBUG_LEVEL == 2 */ for (; 0 < _Off; --_Off) ++_Where; }template<class _FwdIt, class _Diff> inline void _Advance(_FwdIt& _Where, _Diff _Off, forward_iterator_tag) { // increment iterator by offset, forward iterators #if _ITERATOR_DEBUG_LEVEL == 2 if (_Off < 0) _DEBUG_ERROR("negative offset in advance"); #endif /* _ITERATOR_DEBUG_LEVEL == 2 */ for (; 0 < _Off; --_Off) ++_Where; }template<class _BidIt, class _Diff> inline void _Advance(_BidIt& _Where, _Diff _Off, bidirectional_iterator_tag) { // increment iterator by offset, bidirectional iterators for (; 0 < _Off; --_Off) ++_Where; for (; _Off < 0; ++_Off) --_Where; }template<class _RanIt, class _Diff> inline void _Advance(_RanIt& _Where, _Diff _Off, random_access_iterator_tag) { // increment iterator by offset, random-access iterators _Where += _Off; }template<class _InIt, class _Diff> inline void advance(_InIt& _Where, _Diff _Off) { // increment iterator by offset, arbitrary iterators _Advance(_Where, _Off, _Iter_cat(_Where)); }
//获取硬件线程数量 static unsigned int hardware_concurrency() _NOEXCEPT { // return number of hardware thread contexts return (::Concurrency::details::_GetConcurrency()); }
阅读全文
0 0
- C++并发编程——在运行时选择线程数量
- [C++11 并发编程] 04 - 动态选择并发线程的数量
- 线程池控制并发数量
- 并发编程——线程安全性
- Java并发编程——线程中断
- 并发编程——线程通信
- 并发编程——线程同步
- 【Java并发编程实践】— 线程安全
- 并发编程 — 详解线程池
- 并发编程 — 初解线程池
- 并发编程 — 详解线程池
- 《Java并发编程》之线程中断与终止线程运行
- 《Java并发编程》之线程中断与终止线程运行
- C++并发编程学习——3.在线程间共享数据
- 并发编程三——守护线程和线程阻塞
- Java并发编程-03-守护线程的创建和运行
- java并发编程(二)----创建并运行java线程
- GCD并发线程数量控制技术
- Python类的方法(method):super的用法
- linux 下使用 tc 模拟网络延迟和丢包
- Java基础之HashMap阅读总结
- NVcaffe源码阅读——Net&Solver
- 前序和中序序列重建二叉树
- C++并发编程——在运行时选择线程数量
- QT-程序分辨率和居中显示
- 程序员找工作时的技巧
- 文档/视图架构 ing
- JAVA 语言的主要特性
- Hello world题解c++
- 20170731jenkins安装、配置以及使用(二)
- JDK1.7ConcurrentHashMap源码分析
- Window ffmpeg 推摄像头音视频流到服务器